使用 JWT 和路由的 Express REST API

Posted

技术标签:

【中文标题】使用 JWT 和路由的 Express REST API【英文标题】:Express REST API with JWT and Routes 【发布时间】:2020-10-09 07:04:04 【问题描述】:

我正在尝试使用 JWT 身份验证创建 Express API。

但是,我想知道如何最好地允许用户只访问他们自己的资源。

例如,如果有一个 id 为 1 的用户,并且每个用户在数据库中都有一个书籍列表:

ID 已经是 JWT 令牌的一部分,但通常会向 /users/1/books 之类的请求请求获取属于用户 1 的所有书籍。 我的路线通常仍然看起来像这样,我只需检查令牌中的 id 是否与发出请求的相同,还是有其他/更简单的方法?

感谢您的帮助!

【问题讨论】:

【参考方案1】:

当用户发送登录凭据时,检查数据库是否存在电子邮件,如果存在则检查密码是否匹配。如果用户成功登录,您将创建令牌。

 const token = jwt.sign( _id: user._id, email: user.email , "this-is-secret", 
      expiresIn: "1h",
    );

这个令牌被发送到浏览器,每当用户发出请求时,它会手动将此令牌附加到请求中,并将请求发送到您的服务器。您可以使用密钥(在本例中为“this-is-secret”)检查令牌是否有效。

   const  decodedToken = jwt.verify(token, "this-is-secret") 
   req.userId = decodedToken.userId;

现在“userId”已附加到 req 对象。现在,当您从数据库中获取数据时,您正在获取的项目,您编写一个查询(实现取决于您使用的数据库)

  book.userId=req.userId

【讨论】:

【参考方案2】:

您可以根据用户角色或 id 定义一些访问权限权限。 示例:角色:root, admin, staff

然后,在您的路由中,您可以检查该用户是否具有访问功能的权限,或者您可以在控制器级别检查访问权限。

需要定义User、UserModel之间的模型关系。据我了解,在您的情况下,您需要在 UserModel 和 BooksModels 之间建立关系。

UserModel hasMany BooksModel

调用 findOne() 检索特定用户的数据时,只需定义 include: 'aliasModelName' 即可检索用户相关的图书数据。

通过这种方式,您只能有 1 个端点 users/:id 来检索用户数据和图书数据。这取决于您真正想要什么,您还可以拥有一个端点 users/:id/books 来获取属于该用户的所有书籍。

您的模型定义将变为

BooksModel 属于 UserModel

如果您使用 hasMany,您只需一个查询即可获得所需的所有结果。

希望这会有所帮助!

【讨论】:

以上是关于使用 JWT 和路由的 Express REST API的主要内容,如果未能解决你的问题,请参考以下文章

MEAN Stack - 仅在某些 REST 方法上使用 jwt 和 express-restify-mongoose

在nodejs,express和jwt中为相同的路由添加多个授权

使用 GraphQL 和 jwt-express 绕过 JWT

express-jwt 通过路由处理特定的秘密密码

在 Node.js 中使用 express-jwt 令牌保护非 api (res.render) 路由

Node.js 和 Express 排除路由表单 JWT 中间件