springboot项目使用jwt生成token

前言

后端是springcloud,前端是用react写的,之前用过session或者redis保存登录态,听了一位朋友的推荐,使用jwt做token校验

portal

portal项目负责用户登录第三方绑定等用户相关功能

引入jar包
 <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-api</artifactId>
            <version>0.10.5</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-impl</artifactId>
            <version>0.10.5</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-jackson</artifactId>
            <version>0.10.5</version>
            <scope>runtime</scope>
        </dependency>
复制代码
创建util
@Component
@Data
@ConfigurationProperties("jwt")
public class JWTUtil {
    private String issuer;
    private String subject;
    private String audience;
    private String alg;
    private String typ;
    private int expire;
    /**
     *@author: zh
     *@date: 2019-04-28 14:56
     *@desc  生成token
     *@param
     *@return
     */
    public String createToken(Map claims) {
        try {
            Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
            Map header=new HashMap();
            header.put("alg", alg);
            header.put("typ", typ);
            Date nowDate = new Date();
            Date expireDate = getAfterDate(nowDate,0,0,0,0,expire,0);//30分钟过期
            String token = Jwts.builder()
                    .setHeader(header)
                    .setIssuer(issuer)
                    .setSubject(subject)
                    .setAudience(audience)
                    .setClaims(claims)
                    .setExpiration(expireDate)
                    .setIssuedAt(nowDate)
                    .setId(UUID.randomUUID().toString())
                    .signWith(key)
                    .compact();
            return token;
        } catch (JwtException exception){
            exception.printStackTrace();
            throw new BizException(BizStatu.CREATE_TOKEN_FAILED);
        }
    }


    public  Date getAfterDate(Date date, int year, int month, int day, int hour, int minute, int second){
        if(date == null){
            date = new Date();
        }

        Calendar cal = new GregorianCalendar();

        cal.setTime(date);
        if(year != 0){
            cal.add(Calendar.YEAR, year);
        }
        if(month != 0){
            cal.add(Calendar.MONTH, month);
        }
        if(day != 0){
            cal.add(Calendar.DATE, day);
        }
        if(hour != 0){
            cal.add(Calendar.HOUR_OF_DAY, hour);
        }
        if(minute != 0){
            cal.add(Calendar.MINUTE, minute);
        }
        if(second != 0){
            cal.add(Calendar.SECOND, second);
        }
        return cal.getTime();
    }
    /**
     *@author: zh
     *@date: 2019-04-28 14:56
     *@desc  token校验
     *@param
     *@return
     */
    public void verifyToken(int userId,String token) {
        Claims claims=null;
        Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
        try {
            claims = Jwts.parser()
                    .setSigningKey(key)
                    .parseClaimsJws(token)
                    .getBody();
            if(claims==null){
                throw new BizException(BizStatu.CLAIMS_IS_NOT_DEFINED);
            }
            if(claims.getAudience()==null||!audience.equals(claims.getAudience())){
                throw new BizException(BizStatu.TOKEN_IS_WRONG);
            }
            if(claims.getIssuer()==null||!issuer.equals(claims.getIssuer())){
                throw new BizException(BizStatu.TOKEN_IS_WRONG);
            }
            if(claims.getSubject()==null||!subject.equals(claims.getSubject())){
                throw new BizException(BizStatu.TOKEN_IS_WRONG);
            }
            if(claims.get("userId")==null||userId!=claims.get("userId",Integer.class)){
                throw new BizException(BizStatu.TOKEN_IS_WRONG);
            }
            if(claims.getExpiration()==null|| DateUtil.compare_date(new Date(),claims.getExpiration())>0){
                throw new BizException(BizStatu.TOKEN_EXPIRED);
            }
        }catch (JwtException ex) {
            ex.printStackTrace();
        }
    }

}
复制代码
登录调用
        Long userId=user.getLong("id");
        Map claims=new HashMap();
        claims.put("userId",userId);
        String token= jwtUtil.createToken(claims);
复制代码
gateway过滤
@Component
public class TokenFilter implements GatewayFilter, Ordered {
    @Autowired
    private JWTUtil jwtUtil;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        HttpHeaders headers = request.getHeaders();
        String token = headers.getFirst("token");
        String userId = headers.getFirst("userId");
        if (token==null||"".equals(token.trim()) ||userId==null||"".equals(userId.trim()) ) {
            throw new BizException(401,"缺少授权token");
        }
        long id;
        try {
            id = Long.parseLong(userId);
        }catch (NumberFormatException e){
            throw new BizException(BizStatu.USERID_IS_NOT_DEFINED);
        }
        jwtUtil.verifyToken(id,token);


        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
复制代码
token刷新

我这个是朋友合作的项目,写的也很简单,登录授权30分钟,当用户在20分钟之后走网关而且token没到过期时间,这边会生成一个新的token放入到用户header,前端这边写一个过滤器,当返回的header中有token且与本地token不一致,替换掉本地token。这样就可以懒得写中间件刷新token了,用得少,只是并发测试没做,还需要多考虑点东西

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值