maven
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.6.1</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
jwt 工具类
package com.dcy.common.utils;
import cn.hutool.extra.servlet.ServletUtil;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @Author:dcy
* @Description:
* @Date: 2019/11/8 8:40
*/
public class JwtUtil {
public static final int DAY = 3; // 3 天
public static final String SECRET = "XX#$%()(#*!()!KL<><MQLMNQNQJQK sdfkjsdrow32234545fdf>?N<:{LWPW";
public static final String TOKEN_PREFIX = "Bearer";
public static final String HEADER_STRING = "authorization";
public static String generateToken(String userJson) {
HashMap<String, Object> map = new HashMap<>();
//you can put any data in the map
map.put("userJson", userJson);
Calendar now = Calendar.getInstance();
now.setTime(new Date());
now.set(Calendar.DATE, now.get(Calendar.DATE) + DAY);
String jwt = Jwts.builder()
.setClaims(map) //
.setExpiration(now.getTime())//过期时间
.signWith(SignatureAlgorithm.HS512, SECRET)//SECRET是加密算法对应的密钥,这里使用额是HS256加密算法
.compact();
return jwt;
}
public static String validateToken(String token) {
if (token != null) {
// parse the token.
Map<String, Object> body = Jwts.parser()
.setSigningKey(SECRET)
.parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
.getBody();
String userJson = (String) (body.get("userJson"));
if (userJson == null || userJson.isEmpty()) {
throw new TokenValidationException("Wrong token without username");
} else {
return userJson;
}
} else {
throw new TokenValidationException("Missing token");
}
}
/**
* 获取token
*
* @param request
* @return
*/
public static String getAuthToken(HttpServletRequest request) {
Cookie cookie = ServletUtil.getCookie(request, JwtUtil.HEADER_STRING);
if (cookie != null) {
return cookie.getValue();
}
return null;
}
static class TokenValidationException extends RuntimeException {
public TokenValidationException(String msg) {
super(msg);
}
}
}
加密
JwtUtil.generateToken(JSON.toJSONString(sysUserInfo1))
解密
JwtUtil.validateToken(token);
web环境中怎么使用
登录的时候加密
@PostMapping("/login")
@ApiOperation(value = "登录")
@ValidResult
public ResponseData login(@RequestBody SysUserInfo sysUserInfo) throws Exception {
// ----------------可以不调用------------------------
SysUserInfo sysUserInfo1 = iSysUserInfoService.getOne(Wrappers.<SysUserInfo>lambdaQuery().eq(SysUserInfo::getUsername, sysUserInfo.getUsername()));
if (sysUserInfo1 == null) {
throw new Exception("用户名和密码错误,请重新输入");
}
if ("1".equals(sysUserInfo1.getUserStatus())) {
throw new Exception("用户已锁定");
}
if (!BPwdEncoderUtil.matches(sysUserInfo.getPassword(), sysUserInfo1.getPassword().replace("{bcrypt}", ""))) {
throw new Exception("用户名和密码错误,请重新输入");
}
List<Map<String, Object>> moduleResourcesList = iSysModuleResourcesService.getModuleByUserId(sysUserInfo1.getUserId());
// 存到redis中
redisTemplate.opsForValue().set(CommonConstant.REDIS_USER_MODULE_LIST_KEY + sysUserInfo1.getUserId(), moduleResourcesList);
sysUserInfo1.setPassword(null);
sysUserInfo1.setPermissionSet(iSysUserInfoService.getPermissionListByUserId(sysUserInfo1.getUserId()));
sysUserInfo1.setGrantedAuthoritySet(iSysUserInfoService.getAuthRoleSetByUserId(sysUserInfo1.getUserId()));
return ResponseData.success(200,"请求成功",JwtUtil.generateToken(JSON.toJSONString(sysUserInfo1)));
}
在定义getUserInfo接口,根据加密信息获取基本信息
@GetMapping("/getUserInfo")
@ApiOperation(value = "获取用户信息")
public ResponseData getUserInfo(HttpServletRequest request) throws Exception {
String authorization = JwtUtil.getAuthToken(request);
String userJson = JwtUtil.validateToken(authorization);
SysUserInfo sysUserInfo = JSON.parseObject(userJson, SysUserInfo.class);
sysUserInfo.setPassword(null);
return ResponseData.success(sysUserInfo);
}
定义拦截器
package com.dcy.filter;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.dcy.common.constant.CommonConstant;
import com.dcy.common.model.ResponseData;
import com.dcy.common.utils.JwtUtil;
import com.dcy.modules.user.model.SysUserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;
/**
* @Author:dcy
* @Description:
* @Date: 2019/11/8 8:51
*/
public class UserAuthRestInterceptor extends HandlerInterceptorAdapter {
private final AntPathMatcher antPathMatcher = new AntPathMatcher();
private static final String ADMIN_USER_TYPE = "0";
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//取header 的内容
String token = JwtUtil.getAuthToken(request);
if (StrUtil.isNotBlank(token)) {
//验证token
String userJson = JwtUtil.validateToken(token);
// 转换对象
SysUserInfo sysUserIno = JSON.parseObject(userJson, SysUserInfo.class);
if (sysUserInfo != null){
return true;
}
} else {
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter out = response.getWriter();
out.append(JSON.toJSONString(ResponseData.error(3000,"没有token")));
return false;
}
return super.preHandle(request, response, handler);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
super.afterCompletion(request, response, handler, ex);
}
/**
* 获取请求中的url
*
* @param url
* @return
*/
private String getUrl(String url) {
//获取当前访问url
int firstQuestionMarkIndex = url.indexOf("?");
if (firstQuestionMarkIndex != -1) {
return url.substring(0, firstQuestionMarkIndex);
}
return url;
}
}
定义不拦截url
在application.yml中定义ignored变量
ignored: |
/login,/v2/*,/webjars/**,/**/favicon.ico,/swagger-resources/**,/druid/**,/dict/getDictListByType,/dict/getDictTreeListByGroupType,/swagger-ui.html,/file/**,/user/getUserInfoByUsername,/user/registerUser,
/depa/getHosList,/depa/getSubListByHosId
| 是换行使用
注入拦截器
/**
* @Author:dcy
* @Description:
* @Date: 2019/11/8 8:47
*/
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Value("${ignored}")
private List<String> ignored;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// token拦截器 获取用户信息
registry.addInterceptor(userAuthRestInterceptor()).addPathPatterns("/**").excludePathPatterns(ignored);
}
@Bean
public UserAuthRestInterceptor userAuthRestInterceptor(){
return new UserAuthRestInterceptor();
}
}
思路和代码都已经提供,其他的靠大家了。
拦截器写的比较简单,因为我写的业务不太符合大家的,所有我的代码没粘出来,自己可以进行自己的业务处理,比如URL判断某个角色是否能访问等等。