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<String,Object> 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<String,Object> map = new HashMap<>(); 
 | 
        map.put("id",payloads.getId()); 
 | 
//        Map<String,Object> 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<String, Object> 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; 
 | 
    } 
 | 
} 
 |