欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 名人名企 > SpringBoot Vue使用Jwt实现简单的权限管理

SpringBoot Vue使用Jwt实现简单的权限管理

2024/10/25 12:24:21 来源:https://blog.csdn.net/heiye_007/article/details/140709376  浏览:    关键词:SpringBoot Vue使用Jwt实现简单的权限管理

为实现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 {@Autowiredprivate UserService userService;private static UserService userServiceStatic;@PostConstruct//在spring容器初始化后执行该方法public void setUserService() {userServiceStatic = userService;}//生成Tokenpublic 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、获取tokentoken = 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、用密码签名,解码判断tokentry {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{@Autowiredprivate JwtInterceptor jwtInterceptor;@Overridepublic void configurePathMatch(PathMatchConfigurer configurer) {//指定restcontroller统一接口前缀configurer.addPathPrefix("/api", clazz -> clazz.isAnnotationPresent(RestController.class));}@Overridepublic 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{@Autowiredprivate UserService userService;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {//1、获取tokenString token = request.getHeader("token");if (StrUtil.isBlank(token)) {token = request.getParameter("token");}if (StrUtil.isBlank(token)) {throw new RuntimeException("没有token,请重新登录");}//2、开始认证    解码token,获得userIdString 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、用密码签名,解码判断tokentry {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")@ResponseBodypublic CommonResult<Object> login(@RequestBody User user){user = userService.findByUsernameAndPassword(user);if (user == null) {return CommonResult.failed(001, Message.createMessage("用户名或密码错误!!!"));} else {//生成用户对应的TokenString 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信息,后端进行拦截并解码校验,通过则放行,否则抛异常。如果要抛异常时,返回错误信息给前端,请看链接。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com