SpringBoot快速集成JWT令牌验证用户登录

1. 实现token令牌验证api接口

JWT框架完成token的生成和校验

JSON Web Token ,可以将令牌数据(用户名\请求时间等等)生成json-token令牌在web服务间传输,可以完成信息加密、签名

在这里插入图片描述

2. JWT与SpringBoot整合

引入依赖

<dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.19.0</version>
        </dependency>

编写JWT工具类

package com.example.springbootdemo2023.core.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Date;
import java.util.Map;

/**
 * 模块名称: JWT工具包
 * 模块类型: 工具类
 * 编码人:高靖博
 * 创建时间:2023/3/17
 * 联系电话:18587388612
 */
public class MyJWTUtil {
    
    

    private MyJWTUtil(){
    
    }

    // 过期时间,单位秒
    private static final long EXP_TIME = 60 * 30L;

    // 秘钥关键字
    private static final String SECRET = "www.huawei.com";

    /**
     * 生成token
     * @param userName 登录用户名
     * @return
     */
    // 生成token时,需要添加token信息
    // userName : 签名信息,保证token无法重复或者无法被篡改
    public static String getToken(String userName){
    
    

        // 创建Token构造器
        JWTCreator.Builder builder = JWT.create();

        //设置过期时间,设置什么时候过期:EXP_TIME计算一个过期的日子
        Date date = new Date(System.currentTimeMillis() + EXP_TIME * 1000);

        //创建token
        String sign = builder.withExpiresAt(date)
                .withClaim("userName", userName)
                .withClaim("claimDate", new Date().getTime())
                .sign(Algorithm.HMAC256(SECRET));

        return sign;
    }

    /**
     * 验证签名token
     * @param token
     * @return
     */
    public static boolean verify(String token){
    
    
        try{
    
    
            DecodedJWT verify = JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token);
            System.out.println("------- [token认证通过] ---------");
            System.out.println("------- userName:"+verify.getClaim("userName")+" ---------");
            System.out.println("------- 过期时间:"+verify.getExpiresAt()+" ---------");
            return true;
        }catch (Exception e){
    
    
            return false;
        }
        
        
        
        
    }

}

token拦截器,验证token

package com.example.springbootdemo2023.core.interceptors;

import com.alibaba.fastjson.JSON;
import com.example.springbootdemo2023.core.util.MyJWTUtil;
import org.springframework.boot.configurationprocessor.json.JSONObject;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * 模块名称:token验证拦截器
 * 模块类型:
 * 编码人:高靖博
 * 创建时间:2023/3/1
 * 联系电话:18587388612
 */
public class LoginInterceptor implements HandlerInterceptor {
    
    

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    

        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");

        // 所有的token都要放在请求头中  header
        String token = request.getHeader("token");

        //验证
        if(token==null||token==""){
    
    

            Map<String,String> json = new HashMap<>();
            json.put("msg","认证失败,token不存在!");
            json.put("code","-1");
            PrintWriter writer = response.getWriter();
            writer.write(JSON.toJSONString(json));
            writer.flush();
            writer.close();
            return false;
        }else{
    
    // 验证

            boolean verify = MyJWTUtil.verify(token);
            
            if(verify){
    
    
                return true;
            }else{
    
    
                Map<String,String> json = new HashMap<>();
                json.put("msg","认证失败,token失效!");
                json.put("code","-1");
                PrintWriter writer = response.getWriter();
                writer.write(JSON.toJSONString(json));
                writer.flush();
                writer.close();
                return false;
            }
        }
    }
}

配置拦截器

package com.example.springbootdemo2023.core.config;

import com.example.springbootdemo2023.core.interceptors.LoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 模块名称:拦截器配置类
 * 模块类型:
 * 编码人:高靖博
 * 创建时间:2023/3/1
 * 联系电话:18587388612
 */
// 1. 实现WebMvcConfigurer 接口
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    
    

    //2.重写addInterceptors方法
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    
    
        //3. 注册自定义编写的拦截器
        // 调用addInterceptor,参数传递拦截器实例
        InterceptorRegistration ic = registry.addInterceptor(new LoginInterceptor());
        //设置拦截器的拦截规则
        ic.addPathPatterns("/**");
        //放行拦截器(登录页面、登录请求、静态资源(js、css、img、video、font(字体文件))、阿里druid连接池监控中心、swaggerui)
        ic.excludePathPatterns(
                "/login/test2",
                "/sys/user/doLogin",
                "/js/**",
                "/css/**",
                "/imgs/**",
                "/druid/**",
                "/swagger-ui.html",
                "/v2/**",
                "/webjars/**",
                "/swagger-resources/**",
                "/sys/user/captcha",
                "/sys/platform/**",
                "/sys/files/**");
    }
}

后续前端需要在登录之后保存token令牌信息,我选择的是保存到localstorage中

if (res.code == '0000') {
    
    

console.dir(res.data);
//保存token---保存到localstorage
window.localStorage.setItem("token",res.data.token);

然后在每次请求时都需要将token携带
我选择的是将token放置在header中发送到后端

以下案例基于vue请求守卫实现:

// http request 请求拦截器
// 创建拦截器的对象必须是调用请求的axios对象
service.interceptors.request.use(config => {
    
    
    console.dir("请求拦截器!");
    // 在发送请求之前做些什么
  
  // 只要是所有的请求都需要发送的参数需要添加,就用请求拦截器实现
  //在请求发送之前拼接上token
  config.headers.token = window.localStorage.getItem("token");

	return config;
}, error => {
    
    
	// 对请求错误做些什么
	return Promise.reject(error);
});

至此,简单实现登录验证的效果就实现啦!

猜你喜欢

转载自blog.csdn.net/gjb760662328/article/details/129720177