专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

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了,用得少,只是并发测试没做,还需要多考虑点东西

文章永久链接:https://tech.souyunku.com/42463

未经允许不得转载:搜云库技术团队 » SpringBoot项目使用jwt生成token

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们