1.依赖写入
<!-- jwt token-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
2.配置拦截器Interceptor
- 在interceptor包下新建AuthInterceptor.java
- 配置拦截适配器,错误返回json,正确植入用户信息
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest httpServletRequest,
HttpServletResponse response, Object object) throws IOException {
// 从 http 请求头中取出 token
String token = httpServletRequest.getHeader ("token");
// 检查是否有@PassToken来跳过检测
if (object instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) object;
PassToken passToken=handlerMethod.getMethodAnnotation(PassToken.class);
if(passToken !=null){
return true;
}
}
// 判断是否有token ,无则直接返回json数据
if (token == null) {
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter out = null;
try {
JSONObject res = new JSONObject();
res.put("code",404);
res.put("success", false);
res.put("msg", "用户未登录!");
out = response.getWriter();
out.append(res.toString());
return false;
} catch (Exception e) {
e.printStackTrace();
response.sendError(500);
return false;
}
}
//验证token的正确性,错误直接返回json
try {
String id = JWT.decode (token).getAudience ().get (0);
JWTVerifier jwtVerifier = JWT.require (Algorithm.HMAC256 (id)).build ();
jwtVerifier.verify (token);
//如果验证成功,直接在token中取出数据,并给res下设置用户信息id
httpServletRequest.setAttribute("id",id);
} catch (JWTVerificationException e) {
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter out = null;
try {
JSONObject res = new JSONObject();
res.put("success", false);
res.put("code",404);
res.put("msg", "错误的token!");
out = response.getWriter();
out.append(res.toString());
return false;
} catch (Exception f) {
f.printStackTrace();
response.sendError(500);
return false;
}
}
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 { }
}
3.配置ApplicationConfig全局拦截器
- 在config包下新建applicationConfig.java
- 使用@Configuration来定义配置
@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。
@Configuration
public class ApplicationConfig implements WebMvcConfigurer {
//配置拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
//拦截所有请求,注册Auth拦截器
registry.addInterceptor(new AuthenticationInterceptor())
.addPathPatterns("/**");
}
/**
* 跨域支持
*
* @param registry
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH", "OPTIONS", "HEAD")
.maxAge(3600 * 24);
}
//配置资源处理器
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//寻找静态资源
//根目录下的static路径
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/");
}
//设置系统编码
@Bean
public HttpMessageConverter<String> responseBodyConverter(){
StringHttpMessageConverter converter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
return converter;
}
4.配置自定义注解
- 在annotation包下新建自定义注解接口,由于只需要跳过token验证,在这里我们只需要新建Passtoken就好
- 代码
/**
1. 用来跳过验证的PassToken*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PassToken {
boolean required() default true;
}
5.controller层使用token
@RestController
@RequestMapping("/admin")
public class UserinfoController {
//测试无passtoken
@RequestMapping(value="/test",method = RequestMethod.GET)
public Object demotest(HttpServletRequest request){
//获取拦截器拦截下来的token的用户信息
return request.getAttribute("id");
}
//登录模块,登录不需要token验证,加入passtoken注解
@PassToken
@PostMapping("/login")
public Result Login(){
Date start = new Date();
long currrentTime =System.currentTimeMillis()+60*60*1000;
Date end = new Date(currrentTime);
String token=JWT.create ().withAudience ("123").withIssuedAt (start)
.withExpiresAt (end)
.sign (Algorithm.HMAC256 ("123"));
return token;
}
}
6.使用postman测试我们的项目
- 在头部加入token
- 测试/test是否会返回我们的用户信息