public class AuthenticationInterceptor implements HandlerInterceptor {
    @Autowired
    UserService userService;
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception {
        String token = httpServletRequest.getHeader("token");// 从 http 请求头中取出 token
        // 如果不是映射到方法直接通过
        if(!(object instanceof HandlerMethod)){
            return true;
        }
        HandlerMethod handlerMethod=(HandlerMethod)object;
        Method method=handlerMethod.getMethod();
        //检查是否有passtoken注释,有则跳过认证
        if (method.isAnnotationPresent(PassToken.class)) {
            PassToken passToken = method.getAnnotation(PassToken.class);
            if (passToken.required()) {
                return true;
            }
        }
        //检查有没有需要用户权限的注解
        if (method.isAnnotationPresent(UserLoginToken.class)) {
            UserLoginToken userLoginToken = method.getAnnotation(UserLoginToken.class);
            if (userLoginToken.required()) {
                // 执行认证
                if (token == null) {
                    throw new RuntimeException("无token,请重新登录");
                }
                // 获取 token 中的 user id
                String userId;
                try {
                    userId = JWT.decode(token).getAudience().get(0);
                } catch (JWTDecodeException j) {
                    throw new RuntimeException("401");
                }
                User user = userService.findUserById(userId);
                if (user == null) {
                    throw new RuntimeException("用户不存在,请重新登录");
                }
                // 验证 token
                JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
                try {
                    jwtVerifier.verify(token);
                } catch (JWTVerificationException e) {
                    throw new RuntimeException("401");
                }
                //将验证通过后的用户信息放到请求中
                httpServletRequest.setAttribute("currentUser", user);
                return true;
            }
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, 
                                  HttpServletResponse httpServletResponse, 
                            Object o, ModelAndView modelAndView) throws Exception {

    }
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, 
                                          HttpServletResponse httpServletResponse, 
                                          Object o, Exception e) throws Exception {
    }

spring-boot 集成JWT实现token验证

1、引入JWT依赖,由于是基于Java,所以需要的是java-jwt

<dependency>
      <groupId>com.auth0</groupId>
      <artifactId>java-jwt</artifactId>
      <version>3.4.0</version>
</dependency>

2、需要自定义两个注解

用来跳过验证的PassToken

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserLoginToken {
    boolean required() default true;
}

需要登录才能进行操作的注解UserLoginToken 

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PassToken {
    boolean required() default true;
}

如果不能导入依赖包,手动导入 

import java.lang.annotation.RetentionPolicy;
 
import java.lang.annotation.ElementType;

3、实体类UserInfo简写

package com.presoft.wydl.packs.system.model;

import java.util.Date;

import com.fasterxml.jackson.annotation.JsonFormat;

public class UserInfo {
    private Long id;

    private String rybm;

    private String zh;

    private String mm;

    private String ryxm;
}

4、token的生成方法

package com.presoft.wydl.common.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.presoft.wydl.packs.system.model.UserInfo;

public class JwtUtil {

	public static String getToken(UserInfo user) {
        String token="";
        token= JWT.create().withAudience(user.getRybm())
                .sign(Algorithm.HMAC256(user.getMm()));
        return token;
    }
}

5、接下来需要写一个拦截器去获取token并验证token

6、配置拦截器

@Configuration
public class InterceptorConfig extends   WebMvcConfigurationSupport {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(authenticationInterceptor())
                .addPathPatterns("/**");   
    }
    @Bean
    public AuthenticationInterceptor authenticationInterceptor() {
        return new AuthenticationInterceptor();
    }
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        super.addArgumentResolvers(argumentResolvers);
        argumentResolvers.add(new CurrentUserMethodArgumentResolver());
    }
}



7、登录验证Controller

//登录
	@PassToken
    @RequestMapping(value = "/loginByTele",method = RequestMethod.POST)
    public Object login(HttpServletRequest request ,UserInfoVo vo){
        UserInfo userForBase=userInfoMapper.findBySjhm(vo.getSjhm());
        if(userForBase==null){
            Response response = new Response();
			response.setCode("300");
			response.setMsg("登录失败,用户不存在");
			return response;
        }else {
            if (!userForBase.getMm().equals(vo.getMm())){
                Response response = new Response();
				response.setCode("300");
				response.setMsg("登录失败,密码错误");
				return response;
            }else {
                String token = JwtUtil.getToken(userForBase);
                userForBase.setToken(token);
                Response response = new Response("200","请求成功",userForBase);
    			response.setCode("200");
    			return response;
            }
        }
    }

原文 https://www.jianshu.com/p/e88d3f8151db

 

Logo

前往低代码交流专区

更多推荐