From 69d3f3c48ffe5ccec247ed4b30f319690dcb2f7c Mon Sep 17 00:00:00 2001 From: "wei.zhang2" Date: Fri, 29 Dec 2017 14:31:15 +0800 Subject: [PATCH] 1 --- .../service/impl/TokenServiceDbImpl.java | 99 ++++++++++++++++--- .../service/impl/TokenServiceJWTImpl.java | 19 ++-- 2 files changed, 96 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/boot/security/server/service/impl/TokenServiceDbImpl.java b/src/main/java/com/boot/security/server/service/impl/TokenServiceDbImpl.java index 697ebfb..35347b8 100644 --- a/src/main/java/com/boot/security/server/service/impl/TokenServiceDbImpl.java +++ b/src/main/java/com/boot/security/server/service/impl/TokenServiceDbImpl.java @@ -1,8 +1,17 @@ package com.boot.security.server.service.impl; +import java.security.Key; import java.util.Date; +import java.util.HashMap; +import java.util.Map; import java.util.UUID; +import javax.crypto.spec.SecretKeySpec; +import javax.xml.bind.DatatypeConverter; + +import org.apache.commons.collections4.MapUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -15,6 +24,10 @@ import com.boot.security.server.model.TokenModel; import com.boot.security.server.service.SysLogService; import com.boot.security.server.service.TokenService; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; + /** * token存到数据库的实现类 * @@ -24,6 +37,7 @@ import com.boot.security.server.service.TokenService; @Service public class TokenServiceDbImpl implements TokenService { + private static final Logger log = LoggerFactory.getLogger("adminLogger"); /** * token过期秒数 */ @@ -33,17 +47,23 @@ public class TokenServiceDbImpl implements TokenService { private TokenDao tokenDao; @Autowired private SysLogService logService; + /** + * 私钥 + */ + @Value("${token.jwtSecret}") + private String jwtSecret; + + private static Key KEY = null; + private static final String LOGIN_USER_KEY = "LOGIN_USER_KEY"; @Override public Token saveToken(LoginUser loginUser) { - String token = UUID.randomUUID().toString(); - - loginUser.setToken(token); + loginUser.setToken(UUID.randomUUID().toString()); loginUser.setLoginTime(System.currentTimeMillis()); loginUser.setExpireTime(loginUser.getLoginTime() + expireSeconds * 1000); TokenModel model = new TokenModel(); - model.setId(token); + model.setId(loginUser.getToken()); model.setCreateTime(new Date()); model.setUpdateTime(new Date()); model.setExpireTime(new Date(loginUser.getExpireTime())); @@ -53,7 +73,25 @@ public class TokenServiceDbImpl implements TokenService { // 登陆日志 logService.save(loginUser.getId(), "登陆", true, null); - return new Token(token, loginUser.getLoginTime()); + String jwtToken = createJWTToken(loginUser); + + return new Token(jwtToken, loginUser.getLoginTime()); + } + + /** + * 生成jwt + * + * @param loginUser + * @return + */ + private String createJWTToken(LoginUser loginUser) { + Map claims = new HashMap<>(); + claims.put(LOGIN_USER_KEY, loginUser.getToken());// 放入一个随机字符串,通过该串可找到登陆用户 + + String jwtToken = Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS256, getKeyInstance()) + .compact(); + + return jwtToken; } @Override @@ -71,19 +109,27 @@ public class TokenServiceDbImpl implements TokenService { @Override public LoginUser getLoginUser(String token) { - TokenModel model = tokenDao.getById(token); - return toLoginUser(model); + String string = getUUIDFromJWT(token); + if (string != null) { + TokenModel model = tokenDao.getById(string); + return toLoginUser(model); + } + + return null; } @Override public boolean deleteToken(String token) { - TokenModel model = tokenDao.getById(token); - LoginUser loginUser = toLoginUser(model); - if (loginUser != null) { - tokenDao.delete(token); - logService.save(loginUser.getId(), "退出", true, null); + String string = getUUIDFromJWT(token); + if (string != null) { + TokenModel model = tokenDao.getById(string); + LoginUser loginUser = toLoginUser(model); + if (loginUser != null) { + tokenDao.delete(token); + logService.save(loginUser.getId(), "退出", true, null); - return true; + return true; + } } return false; @@ -96,4 +142,31 @@ public class TokenServiceDbImpl implements TokenService { return JSONObject.parseObject(model.getVal(), LoginUser.class); } + private Key getKeyInstance() { + if (KEY == null) { + synchronized (TokenServiceJWTImpl.class) { + if (KEY == null) {// 双重锁 + byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(jwtSecret); + KEY = new SecretKeySpec(apiKeySecretBytes, SignatureAlgorithm.HS256.getJcaName()); + } + } + } + + return KEY; + } + + private String getUUIDFromJWT(String jwt) { + Map jwtClaims = null; + try { + jwtClaims = Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(jwt).getBody(); + } catch (ExpiredJwtException e) { + log.error("{}已过期", jwt); + return null; + } catch (Exception e) { + throw e; + } + + return MapUtils.getString(jwtClaims, LOGIN_USER_KEY); + } + } diff --git a/src/main/java/com/boot/security/server/service/impl/TokenServiceJWTImpl.java b/src/main/java/com/boot/security/server/service/impl/TokenServiceJWTImpl.java index d79570a..eff1fab 100644 --- a/src/main/java/com/boot/security/server/service/impl/TokenServiceJWTImpl.java +++ b/src/main/java/com/boot/security/server/service/impl/TokenServiceJWTImpl.java @@ -61,11 +61,12 @@ public class TokenServiceJWTImpl implements TokenService { @Override public Token saveToken(LoginUser loginUser) { loginUser.setToken(UUID.randomUUID().toString()); - String jwtToken = createJWTToken(loginUser); cacheLoginUser(loginUser); // 登陆日志 logService.save(loginUser.getId(), "登陆", true, null); + String jwtToken = createJWTToken(loginUser); + return new Token(jwtToken, loginUser.getLoginTime()); } @@ -75,7 +76,7 @@ public class TokenServiceJWTImpl implements TokenService { * @param loginUser * @return */ - public String createJWTToken(LoginUser loginUser) { + private String createJWTToken(LoginUser loginUser) { Map claims = new HashMap<>(); claims.put(LOGIN_USER_KEY, loginUser.getToken());// 放入一个随机字符串,通过该串可找到登陆用户 @@ -101,8 +102,8 @@ public class TokenServiceJWTImpl implements TokenService { } @Override - public LoginUser getLoginUser(String token) { - String string = getUUIDFromJWT(token); + public LoginUser getLoginUser(String jwtToken) { + String string = getUUIDFromJWT(jwtToken); if (string != null) { return redisTemplate.boundValueOps(getTokenKey(string)).get(); } @@ -111,8 +112,8 @@ public class TokenServiceJWTImpl implements TokenService { } @Override - public boolean deleteToken(String token) { - String string = getUUIDFromJWT(token); + public boolean deleteToken(String jwtToken) { + String string = getUUIDFromJWT(jwtToken); if (string != null) { String key = getTokenKey(string); LoginUser loginUser = redisTemplate.opsForValue().get(key); @@ -145,12 +146,12 @@ public class TokenServiceJWTImpl implements TokenService { return KEY; } - private String getUUIDFromJWT(String jwt) { + private String getUUIDFromJWT(String jwtToken) { Map jwtClaims = null; try { - jwtClaims = Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(jwt).getBody(); + jwtClaims = Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(jwtToken).getBody(); } catch (ExpiredJwtException e) { - log.error("{}已过期", jwt); + log.error("{}已过期", jwtToken); return null; } catch (Exception e) { throw e;