SpringBoot 实现登录token,这五步很关键!

参考链接

基于Token的登录流程 - 腾讯云开发者社区-腾讯云 (tencent.com)
Java实现token的生成与验证-登录功能 - 穆晟铭 - 博客园 (cnblogs.com)
java SpringBoot登录验证token拦截器_springboot拦截器验证token_我要用代码向我喜欢的女孩表白的博客-CSDN博客

第一步:导入依赖

pom.xml文件

    <!--jwt-->
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt-api</artifactId>
        <version>0.11.5</version>
    </dependency>
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt-impl</artifactId>
        <version>0.11.5</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt-jackson</artifactId>
        <version>0.11.5</version>
        <scope>runtime</scope>
    </dependency>

第二步:书写工具类

package com.example.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;

import javax.crypto.SecretKey;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 通过JWT制造token,设置token
 */
public class JwtUtil {
    // 这是你的 JWT 密钥,请将其设置为更安全的值
    private static final String SECRET_KEY = "dsfdfsdfdsfefrgssthJBIONPILOVEYOUyueyue";


    /**
     * 创建 JWT
     *
     * @param id        JWT ID
     * @param issuer    签发者
     * @param subject   主题
     * @param ttlHOURS JWT 有效期(小时)
     * @param claims    JWT 声明
     * @return JWT 字符串
     */
    public static String createJwt(String id, String issuer, String subject, long ttlHOURS, Map<String, Object> claims) {

        // 设置 JWT 的签发时间和过期时间
        Instant now = Instant.now();
        Instant exp = now.plus(ttlHOURS, ChronoUnit.HOURS);

        // 创建 JWT Builder
        SecretKey key = Keys.hmacShaKeyFor(SECRET_KEY.getBytes());
        JwtBuilder builder = Jwts.builder()
                .setId(id)
                .setIssuer(issuer)
                .setSubject(subject)
                .setIssuedAt(Date.from(now))
                .setExpiration(Date.from(exp))
                .signWith(key);

        // 添加声明
        if (claims != null) {
            builder.addClaims(claims);
        }

        // 构建 JWT 并返回
        return builder.compact();
    }


    /**
     * 解析 JWT
     *
     * @param jwt JWT 字符串
     * @return JWT 声明
     * @throws JwtException 如果 JWT 无效或已过期
     */
    public static Map<String, Object> parseJwt(String jwt) throws JwtException {

        // 解析 JWT
        SecretKey key = Keys.hmacShaKeyFor(SECRET_KEY.getBytes());
        Claims claims = Jwts.parserBuilder()
                .setSigningKey(key)
                .build()
                .parseClaimsJws(jwt)
                .getBody();

        // 将声明转换为 Map
        // 返回声明
        return new HashMap<>(claims);
    }


}

第三步:创造拦截器

Interceptor.class

package com.example.interceptor;

import com.example.mapper.UserDao;
import com.example.utils.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Interceptor implements HandlerInterceptor {

    @Autowired
    UserDao userDao;
    /**
     * 在请求拦截处理前进行token校验
     *
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

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


        //1.token不存在
        if (token == null){
           throw new RuntimeException("token不存在,请重新登录!");
        }

        //2.token是否正确
        try{
            JwtUtil.parseJwt(token).get("phone");
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException("token验证失败或过期,请重新获取!");
        }

        return true;
    }


}

1.此处验证token是否存在 2.验证解析的jwt中是否含有自己所带的参数

第四步:关联拦截器

InterceptorConfig.class

package com.example.config;

import com.example.interceptor.Interceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Bean
    public Interceptor init(){
        return new Interceptor();
    }
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(init())
                //拦截的URL
                .addPathPatterns("/**")
                //放行的URL
                .excludePathPatterns("/user/**");
    }
}

此处添加拦截配置

第五步:统一异常处理

package com.example.controller.utils;

import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

//作为springMVC的异常处理
//@ControllerAdvice
@RestControllerAdvice
public class ProjectExceptionAdvice {
    //拦截所有的异常处理
    @ExceptionHandler
    public R doException(Exception e) {

        String msg ="服务器异常,请稍后再试";
        String  data = e.getMessage();
        if (data.contains("token")){
            msg = data;
        }
        //记录日志
        //通知运维
        //通知开发
        e.printStackTrace();//注意,打印日志,此处实际开发时容易忽略
        return new R(R.UNDEFINED_CODE, null,msg);

    }
}

此处验证token是使用 字符串中包含“token”字符串,而进行验证。自我感觉这样异常处理不合适请各位大佬指教。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值