说明
- 老项目和新框架项目中用户认证的密码算法不同
- 老项目中使用 cookie + spring session + redis 方式实现会话管理;新框架中采用 jwt + redis 方式
- 现在统一为新框架方式 ,修改老项目中相关内容
步骤
pom.xml
1 2 3 4 5 6
| <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.11.0</version> </dependency>
|
JwtUtil.java
封装 jwt 工具类,实现 token 的生成和解析等
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
| package com.bjtcrj.scm.system.utils;
import com.auth0.jwt.JWT; import com.auth0.jwt.JWTVerifier; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.exceptions.JWTDecodeException; import com.auth0.jwt.interfaces.DecodedJWT; import com.bjtcrj.scm.common.exception.ApplicationRuntimeException; import com.bjtcrj.scm.common.utils.SpringContextUtil; import com.bjtcrj.scm.common.utils.oConvertUtils;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.util.Date;
public class JwtUtil {
public static final long EXPIRE_TIME = 30 * 60 * 1000; public static final String X_ACCESS_TOKEN = "X-Access-Token";
public static boolean verify(String token, String loginname, String secret) { try { Algorithm algorithm = Algorithm.HMAC256(secret); JWTVerifier verifier = JWT.require(algorithm).withClaim("loginname", loginname).build(); DecodedJWT jwt = verifier.verify(token); return true; } catch (Exception exception) { return false; } }
public static String getLoginname(String token) { try { DecodedJWT jwt = JWT.decode(token); return jwt.getClaim("loginname").asString(); } catch (JWTDecodeException e) { return null; } }
public static String sign(String loginname, String secret) { Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME); Algorithm algorithm = Algorithm.HMAC256(secret); return JWT.create().withClaim("loginname", loginname).withExpiresAt(date).sign(algorithm); }
public static String getUserNameByToken(HttpServletRequest request) throws ApplicationRuntimeException { String accessToken = getTokenByRequest(request); String loginname = getLoginname(accessToken); if (oConvertUtils.isEmpty(loginname)) { throw new ApplicationRuntimeException("未获取到用户"); } return loginname; }
public static String getTokenByRequest(HttpServletRequest request) { String token = request.getParameter("token"); if (token == null) { token = request.getHeader(X_ACCESS_TOKEN); } return token; }
public static String getSessionData(String key) { String moshi = ""; if(key.indexOf("}")!=-1){ moshi = key.substring(key.indexOf("}")+1); } String returnValue = null; if (key.contains("#{")) { key = key.substring(2,key.indexOf("}")); } if (oConvertUtils.isNotEmpty(key)) { HttpSession session = SpringContextUtil.getHttpServletRequest().getSession(); returnValue = (String) session.getAttribute(key); } if(returnValue!=null){returnValue = returnValue + moshi;} return returnValue; }
public static void main(String[] args) { String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbm5hbWUiOiJhZG1pbiIsImV4cCI6MTYzNDI2NjI2NX0.Z1B3P0U7zNxc2579TvFHJ49PR9V5-TJfFNeObIXLf6g"; System.out.println(JwtUtil.getLoginname(token)); } }
|
登录认证通过后生成 token,存入 Redis 并返回前端
1 2 3 4 5 6
| String token = JwtUtil.sign(loginname, userpassword);
redisCacheManager.set(CommonConstant.PREFIX_USER_TOKEN + token, token, JwtUtil.EXPIRE_TIME*2 / 1000);
j.setObj(token);
|
前端请求时头部添加 token 信息
后端解析头部 token,并做校验、解析出 loginname
1 2 3
| String loginname = JwtUtil.getUserNameByToken(request);
String loginname = JwtUtil.getUsername(token);
|
其它
用户表字段修改
1 2 3 4 5 6 7 8 9
| alter table SCM_USER modify PASSWORD VARCHAR2(255) /
alter table SCM_USER modify PASSWORDDOWN VARCHAR2(255) /
alter table SCM_USER add SALT varchar2(20) /
|
User.java 、UserDto.java 扩展 salt
1 2 3 4
|
private String salt;
|
UserDao.xml 插入语句添加 salt
1 2 3 4 5
| resultMap、Base_Column_List 添加
insertSelective 中添加
updatePwdBasicByDto 中临时添加-批量更新使用,后删除即可
|
UserService.java getByLoginname返回类型修改
PasswordUtil.java
SpringContextUtil.java
oConvertUtils.java
LoginController.java
Constants.java
1 2 3
| public static final String X_ACCESS_TOKEN = "X-Access-Token";
public static final String PREFIX_USER_TOKEN = "prefix_user_token_";
|
UserController.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
@RequestMapping(value = "/initUserData") public void initUserData(HttpServletRequest request, HttpServletResponse response) throws Exception { List<UserDto> userList = userService.getUserList(new UserDto()); for (UserDto userDto : userList) { String salt = oConvertUtils.randomGen(8); userDto.setSalt(salt); String passwordEncode = PasswordUtil.encrypt(userDto.getLoginname(), "123456", salt); userDto.setPassword(passwordEncode); userService.UpdateBasicPwd(userDto); }
Json j = new Json(); j.setSuccess(true); this.writeJson(j,request, response); }
|
login.jsp
1 2
| //登录成功后保存 token localStorage.setItem("token", result.obj); //token 信息
|