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 实现前后端分离登录认证及授权

手把手教你Shiro整合JWT实现登录认证

SpringBoot+Shiro+Jwt实现登录认证——最干的干货

SpringSecurity整合JWT

springboot整合shiro实现登录认证以及授权

SpringBoot整合Shiro+JWT实现认证及权限校验