目录
- 1 问题
- 2 实现
1 问题
一个springboot 项目,需要token 验证,前端传过来token ,我们一般在项目全局写一个过滤器,去验证前端传过来的token ,如果有哪些接口不需要token验证,那么就排除这些接口,这个也需要配置。
但是这样就有一个问题,那就是不能一直配置不需要token验证的接口
所以现在我们就需要自定义一个注解,如果你认为哪个接口不需要token 验证就可以访问,那么就在这个接口上面写这个自定义的注解就可以了
2 实现
第一步,自定义一个注解
代码语言:javascript复制/**
* 排除token 注解
* */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcludeTokenValidation {
}
第二步,写一个过滤器
代码语言:javascript复制@Slf4j
@Component
public class AuthInterceptor implements HandlerInterceptor {
private static final String TOKEN = "token";
@Autowired
private RedisUtil redisUtil;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
// 检查方法上是否有 @ExcludeTokenValidation 注解
if (handlerMethod.hasMethodAnnotation(ExcludeTokenValidation.class)) {
return true; // 如果有该注解,直接通过,不进行 token 验证
}
}
String token = request.getHeader(TOKEN);
// 从参数中获取token
if (ObjectUtils.isEmpty(token)) {
token = request.getParameter(TOKEN);
}
if (!ObjectUtils.isEmpty(token)){
SysUser loginUser = getUser(token);
UserContext.setUser(loginUser);
} else{
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
output(response, noPermissionMsg("没有对应权限,联系管理员"));
return false;
}
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
//手动清除当前用户上下文的用户对象
UserContext.remove();
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
/**
* 获取用户信息
* @param token
* @return
*/
private SysUser getUser(String token) {
Object o = redisUtil.get(token);
JSONObject userJson = JSONObject.parseObject(o.toString());
SysUser sysUser = JSON.toJavaObject(userJson, SysUser.class);
return sysUser;
}
/**
* 响应体返回
*
* @param response
* @param result
* @throws IOException
*/
private void output(HttpServletResponse response, Result<String> result) throws IOException {
response.setContentType("application/json;charset=UTF-8");
ServletOutputStream outputStream = null;
try {
outputStream = response.getOutputStream();
outputStream.write(JSON.toJSONString(result).getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
e.printStackTrace();
} finally {
outputStream.flush();
outputStream.close();
}
}
/**
* @param msg 消息信息
* @return Result<T> 统一返回
*/
private Result<String> noPermissionMsg(String msg) {
String code = String.valueOf(HttpServletResponse.SC_FORBIDDEN);
Result<String> stringResult = ResultUtil.build(code, msg, null);
return stringResult;
}
}
第三步,全剧配置 这个 过滤器
代码语言:javascript复制@Configuration
public class WebConfig implements WebMvcConfigurer {
@Bean
AuthInterceptor authlInterceptor() {
return new AuthInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
List<String> urls = new ArrayList<>();
urls.add("/favicon.ico");
urls.add("**/swagger-ui.html");
urls.add("/swagger-ui.html/**");
registry.addInterceptor(authlInterceptor()).addPathPatterns("/**").excludePathPatterns(urls);
}
}
第四部,在不想要token 验证的接口上面添加这个自定义注解
第五步,启动项目之后,访问这个接口就可以了