package com.doumee.config.jwt; import com.alibaba.fastjson.JSONObject; import com.doumee.core.model.LoginUserInfo; import com.doumee.core.utils.Constants; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; @Component public class JwtTokenUtil { @Autowired private RedisTemplate redisTemplate; @Resource private JwtProperties jwtProperties; /** * 生成token令牌 * * @param payloads 令牌中携带的附加信息 * @return 令token牌 */ public String generateToken( LoginUserInfo payloads) { if(payloads == null){ return null; } payloads.setLoginDate(new Date()); Map map = new HashMap<>(); map.put("id",payloads.getId()); // Map map = BeanUtil.beanToMap(payloads); return generateTokenDo(payloads); } /** * 从令牌中获取用户名 * * @param token 令牌 * @return 用户名 */ public String getUsernameFromToken(String token) { String username; try { LoginUserInfo claims = getClaimsFromToken(token); username = claims.getUsername(); } catch (Exception e) { username = null; } return username; } public LoginUserInfo getUserInfoByToken(String token) { try { LoginUserInfo claims = getClaimsFromToken(token); return claims; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 判断令牌是否过期 * * @param token 令牌 * @return 是否过期 */ public Boolean isTokenExpired(String token) { try { LoginUserInfo claims = getClaimsFromToken(token); Date expiration = claims.getLoginDate(); return expiration.before(new Date()); } catch (Exception e) { //验证JWT签名失败等同于令牌过期 return true; } } /** * 刷新令牌 * * @param token 原令牌 * @return 新令牌 */ public String refreshToken(String token) { String refreshedToken; try { LoginUserInfo claims = getClaimsFromToken(token); claims.setLoginDate(new Date()); refreshedToken = generateTokenDo(claims); if(refreshedToken!=null){ redisTemplate.delete(Constants.REDIS_TOKEN_KEY+token);//删除老的token } } catch (Exception e) { refreshedToken = null; } return refreshedToken; } /** * 退出登陆 * * @param token 原令牌 * @return 新令牌 */ public void logout(String token) { try { redisTemplate.delete(Constants.REDIS_TOKEN_KEY+token);//删除老的token } catch (Exception e) { e.printStackTrace(); } } /** * 验证令牌 * * @param token 令牌 * @param userId 用户Id用户名 * @return 是否有效 */ public Boolean validateToken(String token, String userId) { String username = getUsernameFromToken(token); return (username.equals(userId) && !isTokenExpired(token)); } /** * 从claims生成令牌,如果看不懂就看谁调用它 * * @return 令牌 */ private String generateTokenDo(LoginUserInfo userInfo) { Map claims = new HashMap<>(); claims.put("id",userInfo.getId()); Date expirationDate = new Date(System.currentTimeMillis() + jwtProperties.getExpiration()); String token = Jwts.builder().setClaims(claims) .setExpiration(expirationDate) .signWith(SignatureAlgorithm.HS512, jwtProperties.getSecret()) .compact(); redisTemplate.opsForValue().set(Constants.REDIS_TOKEN_KEY+token,JSONObject.toJSONString(userInfo),jwtProperties.getExpiration(), TimeUnit.MILLISECONDS); return token; } /** * 从令牌中获取数据声明,验证JWT签名 * * @param token 令牌 * @return 数据声明 */ private LoginUserInfo getClaimsFromToken(String token) { LoginUserInfo claims; try { String userInfo = (String) redisTemplate.opsForValue().get(Constants.REDIS_TOKEN_KEY+token); claims = JSONObject.toJavaObject(JSONObject.parseObject(userInfo),LoginUserInfo.class); } catch (Exception e) { claims = null; } return claims; } }