其他分享
首页 > 其他分享> > 分布式应用的用户信息检验方案JWT

分布式应用的用户信息检验方案JWT

作者:互联网

目录


 

jwt简介

Json web token(JWT):使用HMAC或RSA算法加密用户信息生成token,存储在客户端(浏览器),客户端请求服务端时携带上token,服务端解密token获取用户信息。
 

优缺点

jwt的组成

token使用2个小数点分隔这三部分。
 

支持多种加密算法,最常用的是 HMAC SHA256。

token可以存储在浏览器的Cookie、Local Storage、Session Storage中,一般存储在Cookie中。

jwt有多种实现方式,java常用的2种jwt实现类库是jjwt、java-jwt。

 

jjwt实现jwt

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>
import com.example.demo.entity.User;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;

/**
 * JWT工具类
 */
public class JWTUtil {

    /**
     * token颁布方
     */
    public static final String ISSUER = "chy.com";


    /**
     * token过期时间,7天
     */
    private static final long EXPIRE = 1000 * 60 * 60 * 24 * 7;


    /**
     * 秘钥
     */
    public static final String SECRET = "chy.com";


    /**
     * token前缀
     */
    public static final String TOKEN_PREFIX = "chy";


    /**
     * 生成token
     */
    public static String generateToken(User user) {
        String token = Jwts.builder()
        		//用户信息
                .claim("id", user.getId())
                .claim("username", user.getUsername())
                .claim("head_img", user.getHeadImg())
                //token颁布方
                .setIssuer(ISSUER)
                //token颁发时间
                .setIssuedAt(new Date())
                //token过期时间
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRE))
                //签名算法、秘钥
                .signWith(SignatureAlgorithm.HS256, SECRET)
                .compact();
        //拼接前缀,可选
        return TOKEN_PREFIX + token;
    }


    /**
     * 解密token得到用户信息
     * 
     * Claims中包含了token中存储的数据,可通过get方法获取,返回值是Object
     * eg. String username = claims.get("username").toString();
     */
    public static Claims checkToken(String token) {
        try {
            final Claims claims = Jwts.parser().setSigningKey(SECRET)
                    .parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
                    .getBody();
            return claims;
        } catch (Exception e) {
            return null;
        }
    }


}

官方github地址:https://github.com/jwtk/jjwt

 

java-jwt实现jwt

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.13.0</version>
</dependency>
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.example.demo.entity.User;

import java.util.Date;

/**
 * JWT工具类
 */
public class JWTUtil {

    /**
     * token颁布方
     */
    public static final String ISSUER = "chy.com";


    /**
     * token过期时间,7天
     */
    private static final long EXPIRE = 1000 * 60 * 60 * 24 * 7;


    /**
     * 秘钥
     */
    public static final String SECRET = "chy.com";


    /**
     * token前缀
     */
    public static final String TOKEN_PREFIX = "chy";


    /**
     * 生成token
     */
    public static String generateToken(User user) {
        try {
            //签名算法、秘钥
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            String token = JWT.create()
                    //用户信息
                    .withClaim("id", user.getId())
                    .withClaim("username", user.getUsername())
                    .withClaim("head_img", user.getHeadImg())
                    //token颁布方
                    .withIssuer(ISSUER)
                    //token颁发时间
                    .withIssuedAt(new Date())
                    //token过期时间
                    .withExpiresAt(new Date(System.currentTimeMillis() + EXPIRE))
                    .sign(algorithm);
            return token;
        } catch (JWTCreationException exception) {
            //Invalid Signing configuration | Couldn't convert Claims.
            return null;
        }
    }


    /**
     * 解密token得到用户信息
     * 
     * //获取token中所有的claim(封装的用户信息)
     * Map<String, Claim> claims = decodedJWT.getClaims();
     * //get()获取到的是Claim类型,需要用asXxx()转一下
     * String string = claims.get("username").asString();
     */
    public static DecodedJWT checkToken(String token) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            JWTVerifier verifier = JWT.require(algorithm)
                    .withIssuer(ISSUER)
                    .build();
            DecodedJWT decodedJWT = verifier.verify(token);
            return decodedJWT;
        } catch (JWTVerificationException exception) {
            //Invalid signature|claims
            return null;
        }
    }


}

官方github地址:https://github.com/auth0/java-jwt

 

说明

1、可以加入一些额外的加密操作,增加被被人破解的难度,比如拼接前缀、使用其它加密算法再次加密等。
 

2、用户登录成功后,后端生成token,可以由后端操作HttpServletResponse把token添加到cookie中;也可以直接把token传给前端,由前端添加到cookie中。不管哪种,都需要手动设置cookie的过期时间。
 

3、在网关拦截器处,从HttpServletRequest对象中解析token获取用户信息

String token = httpServletRequest.getHeader("token");

标签:String,JWT,jwt,分布式应用,检验,token,static,import,com
来源: https://blog.csdn.net/chy_18883701161/article/details/113790388