SpringBoot Vue使用Jwt实现简单的权限管理
创始人
2024-12-18 00:34:52
0

为实现Jwt简单的权限管理,我们需要用Jwt工具来生成token,也需要用Jwt来解码token,同时需要添加Jwt拦截器来决定放行还是拦截。下面来实现:

1、gradle引入Jwt、hutool插件

    implementation 'com.auth0:java-jwt:3.10.3'     implementation 'cn.hutool:hutool-all:5.3.7' 

2、Jwt工具类,提供静态方法生成token,和根据请求携带的token查找user信息

package com.zzz.simple_blog_backend.utils;  import ......  @Component public class JwtTokenUtils {      @Autowired     private UserService userService;          private static UserService userServiceStatic;          @PostConstruct//在spring容器初始化后执行该方法     public void setUserService() {         userServiceStatic = userService;     }          //生成Token     public static String genToken(String userId,String passwordSign) {         return JWT.create().withAudience(userId)//放入载荷                 .withExpiresAt(DateUtil.offsetHour(new Date(), 2))//2小时后过期                 .sign(Algorithm.HMAC256(passwordSign));//密码签名作为密钥     }          //通过token获取当前登录用户信息     public static User getCurrentUser() {         String token = null;                  HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();         //1、获取token         token = request.getHeader("token");         if (StrUtil.isBlank(token)) {             token = request.getParameter("token");         }         if (StrUtil.isBlank(token)) {             throw new RuntimeException("没有token,请重新登录");         }         String userId;         User user;         try {             userId = JWT.decode(token).getAudience().get(0);         } catch (Exception e) {             throw new RuntimeException("token验证失败,请重新登录!!!");         }         user = userServiceStatic.findById(Integer.parseInt(userId));         if(user==null) {             throw new RuntimeException("用户id不存在,请重新登录!!!");         }         //3、用密码签名,解码判断token 		try { 			JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build(); 			jwtVerifier.verify(token); 		} catch (JWTVerificationException e) { 			throw new CustomException(001, "token验证失败,请重新登录!!!"); 		}         return user;     } } 

3、Jwt拦截器

SpringBoot添加拦截器,excludePathPatterns可以指定不拦截的页面,RestController指定了请求前缀,控制器类要用@RestController代替@ControlleraddInterceptor添加了jwtInterceptor拦截器。

package com.zzz.simple_blog_backend.config;  import ...  @Configuration public class WebConfig implements WebMvcConfigurer{      @Autowired     private JwtInterceptor jwtInterceptor;          @Override     public void configurePathMatch(PathMatchConfigurer configurer) {         //指定restcontroller统一接口前缀         configurer.addPathPrefix("/api", clazz -> clazz.isAnnotationPresent(RestController.class));     }      @Override     public void addInterceptors(InterceptorRegistry registry) {         // 加自定义拦截器  给特定请求放行         registry.addInterceptor(jwtInterceptor).addPathPatterns("/api/**")         .excludePathPatterns("/api/user/login","/api/user/register");     } } 

仔细的童靴会发现JwtTokenUtils.getCurrentUser()方法和JwtInterceptor的拦截方法很像,主要区别就在if(user.getRole()!=0)的判断。所以JwtInterceptor只会给管理员放行,如果需要给普通用户放行而未登录用户不放行,那请求路径先添加到excludePathPatterns,并且控制类对应的响应方法第一句就先调用JwtTokenUtils.getCurrentUser()判断是否用户已登录。

package com.zzz.simple_blog_backend.config;  import ......  @Component public class JwtInterceptor implements HandlerInterceptor{          @Autowired     private UserService userService;      @Override     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)             throws Exception {          //1、获取token         String token = request.getHeader("token");         if (StrUtil.isBlank(token)) {             token = request.getParameter("token");         }         if (StrUtil.isBlank(token)) {             throw new RuntimeException("没有token,请重新登录");         }         //2、开始认证    解码token,获得userId         String userId;         User user;         try {             userId = JWT.decode(token).getAudience().get(0);         } catch (Exception e) {             throw new RuntimeException("token验证失败,请重新登录!!!");         }         user = userService.findById(Integer.parseInt(userId));         if(user==null) {             throw new RuntimeException("用户id不存在,请重新登录!!!");         }         if(user.getRole()!=0) {             throw new RuntimeException("非管理员账号,无权访问!!!");         }         //3、用密码签名,解码判断token         try {             JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();             jwtVerifier.verify(token);         } catch (JWTVerificationException e) {             throw new RuntimeException("token验证失败,请重新登录!!!");         }         //token验证成功,放行         return true; //        return HandlerInterceptor.super.preHandle(request, response, handler);     } } 

4、前后端登录操作

登录后 后端返回带token不带密码的user数据

    @PostMapping("user/login")     @ResponseBody     public CommonResult login(@RequestBody User user){                  user = userService.findByUsernameAndPassword(user);                  if (user == null) {             return CommonResult.failed(001, Message.createMessage("用户名或密码错误!!!"));         } else {             //生成用户对应的Token             String token = JwtTokenUtils.genToken(user.getId().toString(), user.getPassword());             user.setToken(token);             //不传输密码             user.setPassword("");             return CommonResult.success(user);         }     }  

前端保存带token的user

//axios的post请求成功后操作    localStorage.setItem("user",JSON.stringify(response.data.data));//保存用户信息 

5、前端每次请求都携带token信息

假设已安装axios,Axios.interceptors.request拦截用户所有请求,添加token信息后再发送请求,这样后端就可以判断了。

import Axios from 'axios'  Vue.prototype.$http = Axios; //添加向后端发起请求的服务器地址前缀 Axios.defaults.baseURL=AIOS_BASE_URL;   // "http://127.0.0.1/api" //设置请求超时时间 Axios.defaults.timeout=5000;  //axios拦截器 //对接口request拦截 Axios.interceptors.request.use(function(config){ 	 	//发起增删改查请求时,带上token认证 	var user = localStorage.getItem("user"); 	if(user){ 		config.headers["token"] = JSON.parse(user).token; 	} 	 	return config; }) //携带证书 session id 跨域请求的话需要 Axios.defaults.withCredentials = true 

总结

Jwt实现权限管理的原理是登录成功后 后端端生成token密钥,随着用户信息发送给客户端,客户端接受并保存信息到本地localStorage。以后每次需要权限验证时,根据客户端返回的携带token信息,后端进行拦截并解码校验,通过则放行,否则抛异常。如果要抛异常时,返回错误信息给前端,请看链接。

相关内容

热门资讯

研究成果!四川途游小程序辅助软... 研究成果!四川途游小程序辅助软件(辅助挂)开挂透视辅助神器(原来是真的挂)-哔哩哔哩该软件可以轻松地...
透视好牌!wepoker智能辅... 您好,wepoker智能辅助插件这款游戏可以开挂的,确实是有挂的,需要了解加去威信【13670430...
有了最新消息!wepoker-... 有了最新消息!wepoker-h5下载,新天道辅助软件,切实有挂(了解辅助教程)-哔哩哔哩1、下载好...
今天上午!至友互娱情怀辅助软件... 今天上午!至友互娱情怀辅助软件,闲来辅助最新版下载,黑科技教程(真是存在有挂)-哔哩哔哩1、每一步都...
科技通报!宝宝浙江游戏辅助是真... 科技通报!宝宝浙江游戏辅助是真的假的(辅助挂)开挂透视辅助攻略(其实是真的挂)-哔哩哔哩1、玩家可以...
这一问题亟待解决!pokemm... 这一问题亟待解决!pokemmo手机版脚本免费,新518互游插件下载,原来是有挂(推荐第三方教程)-...
今天下午!吉祥填大坑免费脚本,... 今天下午!吉祥填大坑免费脚本,顺欣茶楼辅助视频,揭秘教程(切实存在有挂)-哔哩哔哩1、吉祥填大坑免费...
分享给玩家!佛手在线辅助(辅助... 分享给玩家!佛手在线辅助(辅助挂)开挂透视辅助神器(一贯是真的挂)-哔哩哔哩1、佛手在线辅助机器人多...
更值得关注的是!xpoker辅... 更值得关注的是!xpoker辅助器,情怀莆仙开挂,其实有挂(总结第三方教程)-哔哩哔哩情怀莆仙开挂辅...
据报道!榕城510k脚本,微信... 据报道!榕城510k脚本,微信边锋辅助下载,详细教程(一贯真的有挂)-哔哩哔哩1、起透看视 微信边锋...