在使用spring执行rest api之前有啥方法可以验证令牌

Posted

技术标签:

【中文标题】在使用spring执行rest api之前有啥方法可以验证令牌【英文标题】:Is there any way to validate token before execution of rest api using spring在使用spring执行rest api之前有什么方法可以验证令牌 【发布时间】:2016-05-29 04:27:42 【问题描述】:

我已经为 rest 控制器配置了 spring boot。 我创建了许多 api,但我需要在乞求时验证每个 api 中的令牌信息,用户是否已授权或不基于提供的令牌。

在登录期间,我正在生成令牌,该令牌在每个 api 中都需要用于访问信息。如果令牌无效,那么我需要返回消息Sorry, your provided token information has been expired or not exists.

下面是我的api。

@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 中删除相同的代码并需要使用一个通用功能。

【问题讨论】:

【参考方案1】:

您可以使用 HandlerInterceptor 来处理您的令牌。

HandlerInterceptor.preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 将在任何 RequestMapping 之前执行。

preHandle中验证您的令牌。如果令牌有效,则继续,否则抛出异常,控制器建议将处理其余部分。

暴露 MappedInterceptor 的 bean 类,spring 会自动加载 HandlerInterceptor bean 包含的内容。

ControllerAdviceExceptionHandler 可以捕获异常并返回错误信息

完整示例

@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;
        
    


【讨论】:

太棒了;它为我工作,但有什么方法可以检查选定的 api,因为某些 api 无需令牌即可访问。 您可以为 MappedInterceptor 设置 includePatterns 和 excludePatterns。这些模式将为您过滤请求映射。【参考方案2】:
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 和令牌并检查令牌。您需要根据user id 参数更新dao 方法。

【讨论】:

我可以扩展或用作您证明类的注释吗?【参考方案3】:

您可以使用缓存,而不是从数据库中获取令牌并与当前令牌匹配。创建您自己的缓存对象,如Map 或静态string,它将具有最新的令牌。您可以直接将传入的令牌与缓存中的此令牌进行比较。无需每次都访问数据库。

【讨论】:

我是 Spring 新手,在这里我为每个用户生成新的令牌。所以我们需要在每个 api 中验证这一点。客户端应用程序提供的令牌是否有效? 令牌应仅在服务器端进行验证。您不能将您的验证码分享给客户端。 我在每个 api 中都进行相同的验证,但我需要为此创建单独的方法并在每个 api 中使用。该方法自动检查令牌状态,如果有效则执行 api 代码,否则直接从常用方法返回消息。 所以想为所有用户和api编写另一个方法对吗? 是的,我需要创建一个可以在 api 代码执行之前首先检查的通用方法/服务/注释。

以上是关于在使用spring执行rest api之前有啥方法可以验证令牌的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 rest-api 执行 Spring Cloud 任务

Spring RESTFul 客户端——RestTemplate。有啥奇怪的,请告诉我

如何在spring或使用junit获取rest api的执行时间(获得响应的时间)

如何在使用 PayPal rest API 执行付款之前更改运费

Elasticsearch:通过 Spring Boot 创建 REST APIs 来访问 Elasticsearch

有啥方法可以通过 GitHub Rest API v3 获取存储库见解