亲宝软件园·资讯

展开

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

知识追寻者 人气:0

一 前言

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

二 jwt实现登陆认证流程

三 相关介绍jwt

3.1jwt 组成

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

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1ODI4OTc4NDUsInVzZXJuYW1lIjoienN6eHoifQ.vyiExkFWCCmQA3PFYL0jJfIiYGWubngqB0WcgmtHOxg

3.2 jwt优点

四 jwt用户登陆发放token

4.1 pom.xml

项目构件如下

<dependencies>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
   <groupId>com.auth0</groupId>
   <artifactId>java-jwt</artifactId>
   <version>3.4.0</version>
  </dependency>
  <dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
   <optional>true</optional>
  </dependency>
 </dependencies>

4.2jwt工具类

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

/* *
 * @Author lsc
 * <p> JWT工具类 </p>
 * @Param
 * @Return
 */
public class JwtUtil {

 // Token过期时间30分钟
 public static final long EXPIRE_TIME = 30 * 60 * 1000;

 /* *
 * @Author lsc
 * <p> 校验token是否正确 </p>
 * @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
 * <p>生成签名,30min后过期 </p>
 * @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
 * <p> 获得用户名 </p>
 * @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
 * <p> </p>
 */
@Data
public class SysUser {
 private String username;
 private String password;
}

4.4Controller

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

/**
 * @Author lsc
 * <p> </p>
 */
@RestController
public class SysUserController {

 @PostMapping(value = "/login")
 public Map<String, Object> login(@RequestBody SysUser sysUser){
  Map<String, Object> 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
 * <p>token验证拦截器 </p>
 */
@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
 * <p> 模拟查询数据库获得账号密码 </p>
 */
@Service
public class SysUserService {


 public String getPassword(){
  return "zszxz";
 }
}

5.3拦截器配置

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

/* *
 * @Author lsc
 * <p>拦截器配置 </p>
 * @Param
 * @Return
 */
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

 /* *
  * @Author lsc
  * <p> 设置拦截路径 </p>
  * @Param [registry]
  * @Return void
  */
 @Override
 public void addInterceptors(InterceptorRegistry registry) {
  registry.addInterceptor(authenticationInterceptor())
    .addPathPatterns("/**")
    .excludePathPatterns("/login");
 }
 /* *
  * @Author lsc
  * <p> 将拦截器注入context </p>
  * @Param []
  * @Return com.zszxz.jwt.interceptor.JwtInterceptor
  */
 @Bean
 public JwtInterceptor authenticationInterceptor() {
  return new JwtInterceptor();
 }

 /* *
  * @Author lsc
  * <p>跨域支持 </p>
  * @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
 * <p> </p>
 */
@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/

加载全部内容

相关教程
猜你喜欢
用户评论