我为休息控制器配置了弹簧启动。 我创建了很多api,但是我需要在每个api中验证我的令牌信息,用户是否被授权或不基于提供的令牌。
在登录期间,我生成令牌,该令牌是每个api中访问信息所需的令牌。如果令牌无效,那么我需要返回消息Sorry, your provided token information has been expired or not exists.
@RequestMapping(value="/delete", method= RequestMethod.DELETE)
public Map<String, Object> delete(@RequestBody String reqData,HttpServletRequest request) {
Map<String, Object> m1 = new HashMap<String,Object>();
JSONObject jsonData = new JSONObject(reqData);
Token token= tokenDao.getByTokenCode(jsonData.getString("token"));
if(token==null){
m1.put("status", "error");
m1.put("message", "Sorry, your provided token information expired or not exists.");
return m1;
}
//here my logic to remove user from database.
}
有没有办法在服务方法或使用注释中检查令牌功能,所以我需要在每个api中删除相同的代码,并且需要使用一个通用功能。
答案 0 :(得分:8)
您可以使用 HandlerInterceptor 来处理令牌。
HandlerInterceptor.preHandle(HttpServletRequest请求,HttpServletResponse响应,对象处理程序)将在任何RequestMapping之前执行。
在 preHandle 中验证您的令牌。如果令牌有效则继续,否则抛出异常,控制器建议将处理其余的。
暴露MappedInterceptor的bean类,spring将自动加载HandlerInterceptor bean包含。
ControllerAdvice 和 ExceptionHandler 可以捕获异常并返回错误消息
完整示例
@RestController
@EnableAutoConfiguration
public class App {
@RequestMapping("/")
public String index() {
return "hello world";
}
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
public static class MyException extends RuntimeException {
}
@Bean
@Autowired
public MappedInterceptor getMappedInterceptor(MyHandlerInterceptor myHandlerInterceptor) {
return new MappedInterceptor(new String[] { "/" }, myHandlerInterceptor);
}
@Component
public static class TestBean {
public boolean judgeToken(HttpServletRequest request) {
String token = request.getParameter("token");
if (token == null) {
throw new MyException();
}
return true;
}
}
@Component
public static class MyHandlerInterceptor implements HandlerInterceptor {
@Autowired
TestBean testBean;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return testBean.judgeToken(request);
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception ex) throws Exception {
}
}
@ControllerAdvice
public static class MyExceptionHandler {
@ExceptionHandler(MyException.class)
@ResponseBody
public Map<String, Object> handelr() {
Map<String, Object> m1 = new HashMap<String, Object>();
m1.put("status", "error");
m1.put("message", "Sorry, your provided token information expired or not exists.");
return m1;
}
}
}
答案 1 :(得分:1)
public class TokenVallidation
{
public static boolean tokenValidation(user id, String token){
Token token= tokenDao.getByTokenCode(id,jsonData.getString("token"));
if(token==null){
m1.put("status", "error");
m1.put("message", "Sorry, your provided token information expired or not exists.");
return false;
}
else{
return true;
}
}
}
用于控制器传递用户ID和令牌并检查令牌。您需要根据dao
参数更新user id
方法。
答案 2 :(得分:0)
您可以使用缓存,而不是从数据库获取令牌并与当前令牌匹配。创建自己的缓存对象,如Map
或静态string
,它将具有最新的令牌。并且您可以直接将传入令牌与来自缓存的此令牌进行比较。无需每次都打到数据库。