赞
踩
JWT就不多介绍了
传统的shiro和SpringSecurity安全框架需要Session,重启后Session会丢失,或者将Session存入redis也行,但是相对比较繁琐。利用JWT可以很轻松的实现Token的认证,在前后端分离的情况下,JWT也显得非常的简易。
依赖
- <dependency>
- <groupId>com.auth0</groupId>
- <artifactId>java-jwt</artifactId>
- <version>3.4.0</version>
- </dependency>
登录请求生成token,第一个参数传入ID,表明是哪个用户,第二个参数是对token进行加密,我们都用密码进行加密。
- String token = JWT.create().withAudience(user.getId() + "")
- .sign(Algorithm.HMAC256(user.getPwd()));
写一个notoken注解,此注解适用于方法上,用来表明某个请求不需要token
- @Target({ ElementType.METHOD, ElementType.TYPE })
- @Retention(RetentionPolicy.RUNTIME)
- public @interface NoToken {
- boolean required() default true;
- }
然后利用拦截器进行拦截所有的请求
- public class AuthenticationInterceptor implements HandlerInterceptor {
- @Autowired
- private UserMapper userMapper;
-
- @Override
- public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
- Object object) throws Exception {
-
- // 如果不是映射到方法直接通过
- if (!(object instanceof HandlerMethod)) {
- return true;
- }
- HandlerMethod handlerMethod = (HandlerMethod) object;
- Method method = handlerMethod.getMethod();
- // 检查是否有passtoken注释,有则跳过认证
- if (method.isAnnotationPresent(NoToken.class)) {
- NoToken passToken = method.getAnnotation(NoToken.class);
- if (passToken.required()) {
- return true;
- }
- } else {
- String token = httpServletRequest.getHeader("Authorization");
- // Token不存在
- if (token == null) {
- throw new NeedLoginException();
- }
- // 获取用户ID,如果出错抛异常
- Integer userId;
- try {
- userId = AuthUtils.getUserId(httpServletRequest);
- } catch (JWTDecodeException j) {
- throw new NeedLoginException();
- }
- Staff user = userMapper.selectByPrimaryKey(userId);
- if (user == null) {
- throw new NeedLoginException();
- }
- // 验证Token是否有效
- JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getStaffPwd() + "")).build();
- try {
- jwtVerifier.verify(token);
- } catch (JWTVerificationException e) {
- throw new NeedLoginException();
- }
- 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 {
- }
- }
将拦截器加入到Bean中
- @Configuration
- public class InterceptorConfig extends WebMvcConfigurerAdapter {
- @Override
- public void addInterceptors(InterceptorRegistry registry) {
- registry.addInterceptor(authenticationInterceptor()).addPathPatterns("/**"); // 拦截所有请求,通过判断是否有 @LoginRequired 注解
- }
-
- @Bean
- public AuthenticationInterceptor authenticationInterceptor() {
- return new AuthenticationInterceptor();
- }
- }
从请求头获取Token解析用户ID
- public class AuthUtils {
- public static Integer getUserId(HttpServletRequest req) {
- String token = req.getHeader("Authorization");
- String userId = JWT.decode(token).getAudience().get(0);
- return Integer.parseInt(userId);
- }
- }
这样就可以实现登录了。
如果有哪些请求不需要Token的话,直接可以加上注解@NoToken,在拦截器中判断如果遇到此注解,则不会进行判断Token
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。