赞
踩
首先引入pom依赖
- <dependency>
- <groupId>com.auth0</groupId>
- <artifactId>java-jwt</artifactId>
- <version>3.10.3</version>
- </dependency>
添加拦截器配置类
- @Configuration
- public class InterceptorConfig implements WebMvcConfigurer {
- @Override
- public void addInterceptors(InterceptorRegistry registry) {
- registry.addInterceptor(jwtInterceptor())
- .addPathPatterns("/**") //拦截所有请求 通过判断token是否合法是否需要登录
- .excludePathPatterns("/user/login","/user/register","/**/import","/**/export"); //需要排除的 URL 路径模式的参数,使用它可以指定哪些 URL 不应该被拦截器拦截。
- }
- @Bean
- public JwtInterceptor jwtInterceptor () {
- return new JwtInterceptor();
- }
- }
创建JwtUtil 工具类,生成Token 这里类的注解可以不用@Service 换成@Component 大致功能是相同的 都是将类注入IOC容器中进行管理
- @Service
- public class JwtUtil {
-
- private static UserService staticuserService;
- @Resource
- private UserService userService;
-
- //将动态的 userService 引入 静态方法 方便静态查询当前userToken方法
- @PostConstruct
- public void setUserService(){
- staticuserService = userService;
- }
- /**
- * 生成token
- */
- public static String createToken(User user) {
- Calendar calendar = Calendar.getInstance();
- calendar.add(Calendar.DATE, 7); //默认令牌过期时间7天
- JWTCreator.Builder builder = JWT.create();
- return builder.withClaim("userid",String.valueOf(user.getUserid()))
- //给builder 添加令牌
- .withExpiresAt(calendar.getTime())
- // 以password作为密钥 通过HMAC256算法进行加密
- .sign(Algorithm.HMAC256(user.getPassword()));
- }
-
- public static User getCurrentUser(){
- try {
- // RequestContextHolder顾名思义,持有上下文的Request容器
- HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
- String token = request.getHeader("token");
- if (StrUtil.isNotBlank(token)){
- String userid = JWT.decode(token).getClaim("userid").asString();
- return staticuserService.getById(Integer.parseInt(userid));
- }
- }catch (Exception e) {
- // 获取数据异常
- throw new ServiceException(DATA_ERROR);
- }
- return null;
- }
- }
axios请求接口的js文件设置请求头中的token (不必写在实例里面)
- // request 拦截器
- // 可以自请求发送前对请求做一些处理
- // 比如统一加token,对请求参数统一加密
- request.interceptors.request.use(config => {
- config.headers['Content-Type'] = 'application/json;charset=utf-8';
-
- let user = localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")):{}
- if (user){
- config.headers['token'] = user.token; // 设置请求头
- }
-
- return config
- }, error => {
- return Promise.reject(error)
- });
然后检验发送的请求中 Header是否具有token
通过拦截器的preHandle方法拦截登录的请求头 获取token。此处的ServiceException见我主页的我的自定义异常类
- public class JwtInterceptor implements HandlerInterceptor {
-
- @Autowired
- private UserService userService;
-
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
- String token = request.getHeader("Token");
- if (!(handler instanceof HandlerMethod)){
- return true;
- }
- // 获取失败 token不存在
- if (StrUtil.isBlank(token)){
- throw new ServiceException(TOKEN_NOT_EXIST);
- }
- /**
- * 本处有逻辑错误:通过token寻找userid 若token修改则无法找到User(实际User存在) 控制台报错 220 用户不存在
- */
- String userid;
- try {
- // 在TokenUtils中 用withClaim将token存放至本地存储
- userid = JWT.decode(token).getClaim("userid").asString();
- }catch (JWTDecodeException j){
- throw new ServiceException(TOKEN_ERROR);
- }
-
- // 根据token查询数据库进行对比
- User user = userService.getById(Integer.parseInt(userid));
- if (user == null) {
- throw new ServiceException(ACCOUNT_NOT_EXIST);
- }
-
- // 验证用户密码加签验证token
- JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
- try{
- jwtVerifier.verify(token);
- }catch (JWTVerificationException e){
- throw new ServiceException(ACCOUNT_NOT_EXIST);
- }
- return true;
- }
- }
在login登录实现类下 将token存储在userDto里,通过UserDto类与页面进行数据传输回显
- @Override
- public UserDto login(UserDto userDto) {
- // 通过dto获取的数据查询对应的User
- User one = getUserInfo(userDto);
- if (one != null){
- // 然后将User的数据传到userDto
- BeanUtils.copyProperties(one,userDto);
- String token = JwtUtil.createToken(one);
- userDto.setToken(token);
- return userDto;
- }else {
- throw new ServiceException(LOGIN_MOBLE_ERROR);
- }
- }
此时在控制台则能发现token生成成功。
最后在自己的请求登录的接口下面
将自己的user信息存放在本地存储空间
通过前端的接口拦截器,判断截取的状态码进行提示错误信息
- // response 拦截器
- // 可以在接口响应后统一处理结果
- request.interceptors.response.use(
- response => {
- let res = response.data;
- // 如果是返回的文件
- if (response.config.responseType === 'blob') {
- return res
- }
- // 兼容服务端返回的字符串数据
- if (typeof res === 'string') {
- res = res ? JSON.parse(res) : res
- }
- // 当验证不通过
- if (res.code == '220') {
- ElementUI.Message({
- message : res.message,
- type : 'error'
- })
- }
- return res;
- },
就实现JWT啦!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。