springboot+jwt实现token登陆权限认证的实现

网友投稿 303 2022-12-05


springboot+jwt实现token登陆权限认证的实现

一 前言

此篇文章的内容也是学习不久,终于到周末有时间码一篇文章分享知识追寻者的粉丝们,学完本篇文章,读者将对token类的登陆认证流程有个全面的了解,可以动态搭建自己的登陆认证过程;对小项目而已是个轻量级的认证机制,符合开发需求;

二 jwt实现登陆认证流程

用户使用账号和面发出post请求

服务器接受到请求后使用私钥创建一个jwt,这边会生成token

服务器返回这个jwt给浏览器

浏览器需要将带有token的jwt放入请求头

每次手到客户端请求,服务器验证该jwt的token

验证成功返回响应的资源给浏览器。否则异常处理

三 相关介绍jwt

3.1jwt 组成

JWT的token由三段信息构成的,将这三段信息文本用.连接一起就构成了JWT字符串;

Header 头部(包含了令牌的元数据,并且包含签名和或加密算法的类型)

Payload 负载

Signature 签名/签证

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1ODI4OTc4NDUsInVzZXJuYW1lIjoienN6eHoifQ.vyiExkFWCCmQA3PFYL0jJfIiYGWubngqB0WcgmtHOxg

3.2 jwt优点

简洁(Compact): 可以通过URL,POST参数或者在HTTP header发送,数据量小,传输速度快

自包含(Self-contained):负载中包含了所有用户所需要的信息,避免多次查询数据库

.因为Token是以jsON加密的形式保存在客户端的,所以JWT是跨语言支持;

不需要在服务端保存会话信息,适用于分布式与微服务;

四 jwt用户登陆发放token

4.1 pom.xml

项目构件如下

springboot 2.1;

jwt 3.4.0;

maven 3.5

jdk1.8

postman接口测试

org.springframework.boot

spring-boot-starter-web

com.auth0

java-jwt

3.4.0

org.projectlombok

lombok

true

4.2jwt工具类

jwt工具类中有三个方法,分别是生成数字签名用于用户首次登陆时发送jwt给客户端;其次是校验方法,用于拦截器拦截所有规则内的url,每个请求都必须带有服务器发送的jwt,经过验证后才放行请求;最后一个获得用户名的方法用于查询密钥,在验证jwt时作为参数传入;

/* *

* @Author lsc

*

JWT工具类

* @Param

* @Return

*/

public class JwtUtil {

// Token过期时间30分钟

public static final long EXPIRE_TIME = 30 * 60 * 1000;

/* *

* @Author lsc

*

校验token是否正确

* @Param token

* @Param username

* @Param secret

* @Return boolean

*/

public static boolean verify(String token, String username, String secret) {

try {

// 设置加密算法

Algorithm algorithm = Algorithm.HMAC256(secret);

JWTVerifier verifier = JWT.require(algorithm)

.withClaim("username", username)

.build();

// 效验TOKEN

DecodedJWT jwt = verifier.verify(token);

return true;

} catch (Exception exception) {

return false;

}

}

/* *

* @Author lsc

*

生成签名,30min后过期

* @Param [username, secret]

* @Return java.lang.String

*/

public static String sign(String username, String secret) {

Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);

Algorithm algorithm = Algorithm.HMAC256(secret);

// 附带username信息

return JWT.create()

.withClaim("username", username)

.withExpiresAt(date)

.sign(algorithm);

}

/* *

* @Author lsc

*

获得用户名

* @Param [request]

* @Return java.lang.String

*/

public static String getUserNameByToken(HttpServletRequest request) {

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

DecodedJWT jwt = JWT.decode(token);

return jwt.getClaim("username")

.asString();

}

}

4.3 用户实体

实体中包含用户名,和密码,一切从简;

/**

* @Author lsc

*

*/

@Data

public class SysUser {

private String username;

private String password;

}

4.4Controller

表现层代码用户用户登陆认证,认证成功后发放token给客户端;

/**

* @Author lsc

*

*/

@RestController

public class SysUserController {

@PostMapping(value = "/login")

public Map login(@RequestBody SysUser sysUser){

Map map = new HashMap<>();

String username = sysUser.getUsername();

String password = sysUser.getPassword();

// 省略 账号密码验证

// 验证成功后发送token

String token = JwtUtil.sign(username,password);

if (token != null){

map.put("code", "200");

map.put("message","认证成功");

map.put("token", token);

return map;

}

map.put("code", "403");

map.put("message","认证失败");

return map;

}

}

4.5 测试

测试url http://localhost:8080/login

postman post请求测试参数如下

{

"username": "zszxz",

"password": "zszxz"

}

返回内容如下

{

"code": "200",

"message": "认证成功",

"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1ODI4OTc4NDUsInVzZXJuYW1lIjoienN6eHoifQ.vyiExkFWCCmQA3PFYL0jJfIiYGWubngqB0WcgmtHOxg"

}

五 jwt登陆拦截认证

基于前面已经实现jwt登录认证后发放token给客户端;本节内容就是将token放入请求头中发送请求给服务器;服务器使用拦截器拦截请求对token进行验证;验证成功请求通过,否则请求资源失败;

5.1自定义拦截器

自定义拦截器JwtInterceptor,实现HandlerInterceptor接口,每次请求到达之前都会验证token是否有效;

/**

* @Author lsc

*

token验证拦截器

*/

@Component

public class JwtInterceptor implements HandlerInterceptor {

@Autowired

SysUserService sysUserService;

@Override

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

// 从 http 请求头中取出 token

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

// 如果不是映射到方法直接通过

if(!(handler instanceof HandlerMethod)){

return true;

}

if (token != null){

String username = JwtUtil.getUserNameByToken(request);

// 这边拿到的 用户名 应该去数据库查询获得密码,简略,步骤在service直接获取密码

boolean result = JwtUtil.verify(token,username,sysUserService.getPassword());

if(result){

System.out.println("通过拦截器");

return true;

}

}

return false;

}

@Override

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

}

@Override

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

}

}

5.2 service

/**

* @Author lsc

*

模拟查询数据库获得账号密码

*/

@Service

public class SysUserService {

public String getPassword(){

return "zszxz";

}

}

5.3拦截器配置

拦截器配置中主要定义拦截请求规则,将拦截器注入WebMvcConfigurer;cors跨域处理;

/* *

* @Author lsc

*

拦截器配置

* @Param

* @Return

*/

@Configuration

public class InterceptorConfig implements WebMvcConfigurer {

/* *

* @Author lsc

*

设置拦截路径

* @Param [registry]

* @Return void

*/

@Override

public void addInterceptors(InterceptorRegistry registry) {

registry.addInterceptor(authenticationInterceptor())

.addPathPatterns("/**")

.excludePathPatterns("/login");

}

/* *

* @Author lsc

*

将拦截器注入context

* @Param []

* @Return com.zszxz.jwt.interceptor.JwtInterceptor

*/

@Bean

public JwtInterceptor authenticationInterceptor() {

return new JwtInterceptor();

}

/* *

* @Author lsc

*

跨域支持

* @Param [registry]

* @Return void

*/

@Override

public void addCorsMappings(CorsRegistry registry) {

registry.addMapping("/**")

.allowedOrigins("*")

.allowCredentials(true)

.allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH", "OPTIONS", "HEAD")

.maxAge(3600 * 24);

}

}

5.4Controller

表现层接口用于拦截亲求测试

/**

* @Author lsc

*

*/

@RestController

public class TestController {

@GetMapping(value = "/api/test")

public String get(){

return "zszxz";

}

}

5.5 测试

测试url http://localhost:8080/api/test

发送get请求给服务器,带有请求头,key为token,value为用户首次登陆时返回的token串;

测试返回内容如下

zszxz

六 官网链接

https://jwt.io/introduction/


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Kafka Java Producer代码实例详解
下一篇:SpringMVC 跨重定向请求传递数据的方法实现
相关文章

 发表评论

暂时没有评论,来抢沙发吧~