使用 JWT 保护用于验证客户端的 RESTful API

Posted

技术标签:

【中文标题】使用 JWT 保护用于验证客户端的 RESTful API【英文标题】:Securing a restful API verifying clients with JWT 【发布时间】:2019-12-02 08:18:06 【问题描述】:

我有一个使用 JWT 进行身份验证的 RESTful API。我从客户端收到的第一个调用是 /login 调用,带有以下有效负载(无标头)


     "username" : xxxx,
     "password": wwww

服务器验证用户是否已注册,然后将签名的 JWT 返回给客户端,以便在下一次调用中接收。

我想知道这是否足够安全。如果客户端向我发送客户端 ID / 客户端密码(如在 OAuth 中),我不会检查任何地方,因此我无法验证此调用是来自我的 webapp / 应用程序还是我不知道的外部客户端。我想知道使用 JWT 实现这种行为是否有意义以及如何实现它。

(我知道如何使用 OAuth2,但我现在不想从 JWT 身份验证中转移)

谢谢!

【问题讨论】:

【参考方案1】:

如果我理解正确的话,你应该创建一个类似下面的函数:

function verify(req, res, next) 
   const token = req.header('x-auth-token');

   if (!token) 
       return res.status(401).json(
           msg: 'No token, auth denied'
       );
  

   try 
       const decoded = jwt.verify(token, config.get(YOUR_SECRET_GOES_HERE));
       req.user = decoded.user;
       next();
    catch (err) 
       res.status(401).json(
           msg: 'Token is not valid'
       );
   

对于所有安全的 API 端点,您应该像这样应用它:

router.get('/anyuserinfo', verify, (req, res) => ... 

就是这样。如果没有提供令牌,该函数将发送401 响应。

【讨论】:

我想你在这里验证这个 JWT 是否是由这个服务器检查它的秘密生成的。但我正在考虑第一次登录调用。想象一下,您想限制所有 API 调用都由已知客户端完成(在 OAuth 中,您会给它们一个 client_id 和 client_secret)。我在问使用 JWT auth 是否有类似的东西。 我仍然不确定我是否能理解你。您可以向 JWT 添加有效负载。有效负载可以是您喜欢的任何类型。因此,可以将带有验证信息的对象添加到您发出的令牌中,然后像我上面显示的那样对其进行解码(decoded.user 是有效负载)。如果这不是您需要的 - 那我有点慢) 是的,在这种情况下你是对的。但是想想第一个 /login api 调用。还没有发布 JWT,所以你不能这样做。如果服务器知道客户端,我想在这种情况下(以及以下 api 调用)检查。我在想这个:developer.okta.com/blog/2018/06/29/…(请参阅 client_id 部分)但我不知道是否可以使用 JWT 执行此操作。谢谢:)【参考方案2】:

我想我找到了另一个回答我的 *** 问题: JWT (Json Web Token) Audience "aud" versus Client_Id - What's the difference?

简而言之,在发送新的 JWT 令牌之前,应将 client_id 和 client_secret 以标头形式发送到服务器以进行验证。

【讨论】:

以上是关于使用 JWT 保护用于验证客户端的 RESTful API的主要内容,如果未能解决你的问题,请参考以下文章

如何在 CodeIgniter 3.x 中为来自客户端的每个请求验证 JWT 令牌

保护 NodeJS RESTful API 和 React 客户端应用程序

移动应用程序的 Laravel RESTful API 身份验证

在客户端应用程序上刷新 JWT 和保护会话

RESTful API:仅用于验证的 METHOD/HEADER 组合

前端客户端的用户对象