周刚vk

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

登录功能采用springsecurity安全框架和jwt令牌

 首先需要添加依赖信息

 

 在yml中添加JWT的配置文件

 

 有了上述的配置之后,我们可以准备一个JWT的工具类,方便后面和JWT相关的内容去使用。

先新建一个config的包

 创建2个静态变量,一个使用户名的KEY,另外一个是JWT创建的时间。

还有JWT的密钥和JWT的失效时间,这个我们可以使用@Vaule注解进行

@Component
public class JwtTokenUtil {
    private static final String CLAIM_KEY_USERNAME = "sub";
    private static final String CLAIM_KEY_CREATED = "created";
    @Value("${jwt.secret}")
    private String secret;
    @Value("${jwt.expiration}")
    private Long expiration;

}

 然后我们还要在此类中做一些其他的功能。例如 根据用户名生成Token,也可以生成Token中拿出用户名,也可以判断当前的Token是否失效,是否可以刷新Token

首先第一个方法是生成token,方法名generateToken ,传入的用户信息,使用springsecurity中的UserDetails来获取用户信息。

/**
* 根据用户信息生成token
* @param userDetails
* @return
*/

public String generateToken(UserDetails userDetails){
}

在该方法中先准备一个荷载claims

Map<String ,Object> claims = new HashMap<>();

在claims中添加当前用户信息,以及添加当前的创建时间

claims.put(CLAIM_KEY_USERNAME,userDetails.getUsername());
claims.put(CLAIM_KEY_CREATED,new Date()); 

 然后是返回值,返回一个generateToken的方法,该方法的参数值是荷载claims

return generateToken(claims); 

 上面返回的这个generateToken方法。首先要使用Jwts中的builder方法,设置载荷(setClaims),再设置失效时间(setExpiration),还有签名(SignWith),compact().表示生成jwt。

    public String generateToken(Map<String,Object> claims){
            return Jwts.builder()
                    .setClaims(claims) //先将荷载放入到Jwt中
                    .setExpiration(generateExpirationDate()) //将生效时间放入其中
                    .signWith(SignatureAlgorithm.ES512,secret)//使用ES512算法和密钥
                    .compact();
}

上面的generateToken中generateExoirationDate方法。使用当前的系统时间,加上我们在yml中配置的失效时间长度,即可。

private Date generateExpirationDate() {
return new Date(System.currentTimeMillis()+expiration*1000);
}

根据token解析出用户名

/**
     * 从token中获取登录用户名
     * @param token
     * @return
     */
    public String getUserNameFromToken(String token){

    } 

在该方法中,使用getClaimsFormToken方法,参数为token 获取载荷claims。然后使用claims中的getSubject()方法,获取username。然后把代码try catch一下,把username的值置为空。返回username.具体代码如下:

    /**
     * 从token中获取登录用户名
     * @param token
     * @return
     */
    public String getUserNameFromToken(String token){
        String username;
        try {
            Claims claims = getClaimsFormToken(token);
            username = claims.getSubject();
        } catch (Exception e) {
            username = null;
        }
        return username;
    } 

上面方法中的getClaimsFormToken方法:使用Jwts类获取载荷,并进行返回,如下所示。

private Claims getClaimsFormToken(String token) {
        Claims claims = null;
        try {
            claims = Jwts.parser()
                    .setSigningKey(secret)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return claims;
    } 

判断当前token是否有效的方法。从2个方面进行判断,一方面首先判断当前token是否已经过期。另一方面,判断token荷载中的用户名和传入参数Userdetail中的用户名是否一致。
首先我们需要使用getUserNameFromToken方法获取username,然后 判断username和当前userDetails中的name是否一致,然后再使用isTokenExpired方法判断当前token是否已经过期。

    /**
     * 验证当前的token值是否有效
     * @param token
     * @param userDetails
     * @return
     */
    public boolean validateToken(String token, UserDetails userDetails){
        String username = getUserNameFromToken(token);
        return username.equals(userDetails.getUsername()) && isTokenExpired(token);

    }

上面方法中的 isTokenExpired方法:首先获取当前token的失效的时间。然后判断该时间是否在当前时间之前,如果在当前时间之前,则已经失效。

    /**
     * 判断当前的token是否已经超出失效时间
     * @param token
     * @return
     */
    private boolean isTokenExpired(String token) {
        Date expireDate = getExpiredDateFromToken(token);
        return expireDate.before(new Date());
    } 

 上面方法中的 getExpiredDateFromToken方法是为了从token中获取失效时间,代码如下

 

    /**
     * 从token中获取失效时间
     * @param token
     * @return
     */
    private Date getExpiredDateFromToken(String token) {
        Claims claims = getClaimsFormToken(token);
        return claims.getExpiration();

    }

再写一个方法,判断Token是否可以被刷新,也就是判断当前的token是否已经失效,若已经失效则可以被刷新,若未失效则无需刷新

    /**
     * 判断token是否可以被刷新
     * @param token
     * @return
     */
    public boolean canRefresh(String token){
        return !isTokenExpired(token);
    } 

再写一个刷新Token的方法,先获取荷载,然后把token的过期时间改一下,改成当前时间就可以了。然后再通过新的荷载生成token

    /**
     * 刷新token
     * @param token
     * @return
     */
    public String refreshToken(String token){
        Claims claims = getClaimsFormToken(token);
        claims.put(CLAIM_KEY_CREATED,new Date());
        return generateToken(claims);
    } 

至此,上述JwtTokenUtil类中的所有方法都已经完成,我们再来分析一下,

在该类中,只有一小部分的方法可以对外进行提供,其他都是一些内部的方法

例如从Token中获取登录名,  getUserNameFromToken()

  验证Token是否有效,  ValidateToken()

  判断Token是否可以被刷新,   canRefresh()

  刷新Token,  refreshToken()

 

 

 

 

 

 

 

 

 

 

 

 

posted on 2022-05-18 09:10  小蚂蚁啃地球vk  阅读(156)  评论(0)    收藏  举报