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);
});
至此,简单实现登录验证的效果就实现啦!