SpringBoot整合JWT实现登录认证
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot整合JWT实现登录认证相关的知识,希望对你有一定的参考价值。
参考技术A
1、JWT的构成
- 头部(header):描述该JWT的最基本的信息,如类型以及签名所用的算法。
- 负载(payload):存放有效信息的地方。
- 签证(signature):base64加密后的header、base64加密后的payload和密钥secret加密后组成。
2、整合JWT
2.1 引入JWT依赖
com.auth0
java-jwt
3.18.3
2.2 编写JWTUtils工具类
package com.stock.utils;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.Verification;
import java.util.Calendar;
import java.util.Map;
public class JWTUtils
private static final String SING="@#$%^&*";
// 生成token
public static String getToken(Map map)
Calendar instance = Calendar.getInstance();
instance.add(Calendar.MINUTE,30);
//创建jwt builder
JWTCreator.Builder builder = JWT.create();
//payload
builder.withExpiresAt(instance.getTime());
map.forEach((k,v)->
builder.withClaim(k,v);
);
//设置签名
String token = builder.sign(Algorithm.HMAC256(SING));
return token;
//验证令牌
public static void verifyToken(String token)
JWTVerifier require = JWT.require(Algorithm.HMAC256(SING)).build();
require.verify(token);
//获取token信息
public static DecodedJWT getTokenInfo(String token)
DecodedJWT verify = JWT.require(Algorithm.HMAC256(SING)).build().verify(token);
return verify;
2.3 编写拦截器
public class JWTInterceptor implements HandlerInterceptor
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
if (HttpMethod.OPTIONS.toString().equals(request.getMethod()))
System.out.println("OPTIONS请求,放行");
return true;
HashMap map = new HashMap>();
String token = request.getHeader("token");
try
JWTUtils.verifyToken(token);
return true;
catch (SignatureVerificationException e)
map.put("msg","无效签名!");
catch (TokenExpiredException e)
map.put("msg","token过期!");
catch (AlgorithmMismatchException e)
map.put("msg","token加密算法不一致");
catch (Exception e)
map.put("msg","无效签名!");
map.put("state",404);
map.put("path","/login");
//将map转化为字符串返回给前端
String result = new ObjectMapper().writeValueAsString(map);
response.setContentType("application/json;charset=UTF-8");
response.getWriter().println(result);
return false;
注意:
1、token存放在请求的header中;
2、在前后端分离的项目中,发送的GET/POST请求实则为两次请求。第一次请求为OPTIONS请求,第二次请求才是GET/POST请求;在OPTIONS请求中,不会携带请求头的参数,会导致在拦截器上获取请求头为空,自定义的拦截器拦截成功。第一次请求不能通过,就不能获取第二次的请求。所以需要在拦截器中加上如下代码来判断是否为OPTIONS请求,对于OPTIONS请求直接放过。
if (HttpMethod.OPTIONS.toString().equals(request.getMethod()))
System.out.println("OPTIONS请求,放行");
return true;
2.4 配置拦截器
package com.stock.config;
import com.stock.Interceptors.JWTInterceptor;
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 IntercepterConfg implements WebMvcConfigurer
@Override
public void addInterceptors(InterceptorRegistry registry)
registry.addInterceptor(new JWTInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/login");
2.5 编写Controller
package com.stock.controller;
import com.stock.entity.User;
import com.stock.result.Result;
import com.stock.service.UserService;
import com.stock.utils.JWTUtils;
import com.stock.utils.ResultUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
@RestController
public class LoginController
private UserService userService;
@Autowired
public LoginController(UserService userService)
this.userService = userService;
@PostMapping("/login")
public Result register(User user)
HashMap map = new HashMap>();
map.put("username",user.getUserName());
String token = JWTUtils.getToken(map);
HashMap data = new HashMap>();
data.put("token",token);
return ResultUtils.getresult(200,"登录成功!",data);
@GetMapping("/main")
public Result tomain()
return ResultUtils.getresult(200,"访问成功",null);
2.6使用Postman测试
- 未登录前访问127.0.0.1:8888/main
- 先登录再访问127.0.0.1:8888/main
以上是关于SpringBoot整合JWT实现登录认证的主要内容,如果未能解决你的问题,请参考以下文章
spring boot整合jwt 实现前后端分离登录认证及授权