Springboot-JWT token实现简单登陆

Springboot-JWT token实现登陆

JWT认证过程:

(上图)java

在这里插入图片描述

1.pom.xml

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

2.annotation(定义注解标识)

/** * 用来跳过验证的PassToken * @author Mr. Cheng * @version 1.0 * @date 2020/10/9 0009 17:15 */
@Target({ ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PassToken { 
    boolean required() default true;
}
/** * @author Mr. Cheng * @version 1.0 * @date 2020/10/9 0009 17:15 */
/** * 须要登陆才能进行操做的注解UserLoginToken */
@Target({ ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserLoginToken { 
    boolean required() default true;
}

3.config

  • 先定义一个生成Token 的方法
@Service("TokenService")
public class TokenService { 
    public String getToken(User user) { 
        String token="";
        token= JWT.create().withAudience(user.getId())// 将 user id 保存到 token 里面
                .sign(Algorithm.HMAC256(user.getPassword()));// 以 password 做为 token 的密钥
        return token;
    }
}
  • 配置拦截请求
@Configuration
public class InterceptorConfig implements WebMvcConfigurer { 
    @Override
    public void addInterceptors(InterceptorRegistry registry) { 
        registry.addInterceptor(authenticationInterceptor())
                .addPathPatterns("/**");    // 拦截全部请求,经过判断是否有 @LoginRequired 注解 决定是否须要登陆
    }
    @Bean
    public AuthenticationInterceptor authenticationInterceptor() { 
        return new AuthenticationInterceptor();
    }
}

4.Interceptor

/** * 拦截器: 拦截全部请求 * @author Mr. Cheng * @version 1.0 * @date 2020/10/9 0009 17:14 */
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");
                }
                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 { 

    }
}

5.entity

public class User { 
    String Id;
    String username;
    String password;

    public String getId() { 
        return Id;
    }

    public void setId(String id) { 
        Id = id;
    }

    public String getUsername() { 
        return username;
    }

    public void setUsername(String username) { 
        this.username = username;
    }

    public String getPassword() { 
        return password;
    }

    public void setPassword(String password) { 
        this.password = password;
    }
}
}

6.mapper

public interface UserMapper { 
    User findByUsername(@Param("username") String username);
    User findUserById(@Param("Id") String Id);
}

7.service

@Service("UserService")
public class UserService { 
    @Autowired
    UserMapper userMapper;
    public User findByUsername(User user){ 
        return userMapper.findByUsername(user.getUsername());
    }
    public User findUserById(String userId) { 
        return userMapper.findUserById(userId);
    }

}

8.controller

/** * @author Mr. Cheng * @version 1.0 * @date 2020/10/9 0009 17:14 */
publi
@RestController
@RequestMapping("user")
public class UserController { 
    @Autowired
    UserService userService;
    @Autowired
    TokenService tokenService;
    //登陆
    @PostMapping("/login")
    public Object login( User user){ 
        JSONObject jsonObject=new JSONObject();
        User userForBase=userService.findByUsername(user);
        if(userForBase==null){ 
            jsonObject.put("message","登陆失败,用户不存在");
            return jsonObject;
        }else { 
            if (!userForBase.getPassword().equals(user.getPassword())){ 
                jsonObject.put("message","登陆失败,密码错误");
                return jsonObject;
            }else { 
                String token = tokenService.getToken(userForBase);
                jsonObject.put("token", token);
                jsonObject.put("user", userForBase);
                return jsonObject;
            }
        }
    }
    @UserLoginToken
    @GetMapping("/getMessage")
    public String getMessage(){ 
        return "你已经过验证";
    }
}