RESTful API 如何添加认证和授权?

· 约 11 分钟读完

在开发 RESTful API 时,认证和授权是必不可少的。认证是指验证用户身份,确保请求来自合法的用户;授权是指确定用户是否有权限访问 API 中的某些资源。本文将介绍如何在 RESTful API 中添加认证和授权。

认证

基本认证

基本认证是最常用的一种认证方式,它使用用户名和密码来验证用户身份。在 RESTful API 中,基本认证的实现方式如下:

  1. 客户端发送请求到服务器,请求的头部包含 Authorization 字段,其值为 "Basic base64(username:password)",其中 username 和 password 是用户的用户名和密码,base64 是一种编码方式,用于将用户名和密码转换为字符串。

  2. 服务器收到请求后,解码 Authorization 字段,获取用户名和密码。

  3. 服务器验证用户名和密码是否正确,如果正确则返回请求的资源,否则返回 401 Unauthorized 状态码。

示例代码:

在上面的示例代码中,我们定义了一个 authenticateUser 中间件函数来验证用户身份。该函数首先检查请求头中是否包含 Authorization 字段,然后解码 Authorization 字段获取用户名和密码,最后验证用户名和密码是否正确。如果验证通过,则将用户信息存储在 req.user 中,供后续的路由处理函数使用。

OAuth2 认证

OAuth2 是一种常用的认证协议,它允许用户授权第三方应用程序访问他们的资源。在 OAuth2 认证中,有四种角色:资源拥有者、客户端、授权服务器和资源服务器。其中客户端是指需要访问资源的应用程序,授权服务器是负责验证用户身份并颁发访问令牌的服务器,资源服务器是存储资源的服务器。

OAuth2 认证的流程如下:

  1. 客户端向授权服务器发送请求,请求授权访问资源。

  2. 授权服务器验证客户端身份,并要求用户登录并授权访问请求。

  3. 用户登录并授权访问请求后,授权服务器颁发访问令牌给客户端。

  4. 客户端使用访问令牌向资源服务器发送请求,请求访问资源。

  5. 资源服务器验证访问令牌是否有效,如果有效则返回请求的资源,否则返回 401 Unauthorized 状态码。

示例代码:

在上面的示例代码中,我们定义了一个 authenticateClient 中间件函数来验证客户端身份,该函数检查请求参数中是否包含 client_id 和 client_secret 字段,并验证这些字段的值是否匹配已注册的客户端。如果验证通过,则将客户端信息存储在 req.client 中,供后续的路由处理函数使用。

我们还定义了一个 authenticateUser 中间件函数来验证用户身份,该函数检查请求头中是否包含 Authorization 字段,并解析访问令牌获取用户信息。如果验证通过,则将用户信息存储在 req.user 中,供后续的路由处理函数使用。

在客户端向授权服务器请求授权时,我们使用了模板引擎渲染了一个登录页面,该页面包含了客户端的 client_id 和 redirect_uri,以便用户登录后能够正确跳转回客户端应用程序。

在用户登录后,我们生成了一个访问令牌并将其作为查询参数附加在 redirect_uri 后面,以便客户端应用程序能够正确访问资源。

授权

基于角色的授权

基于角色的授权是最常用的一种授权方式,它将用户分配到不同的角色,每个角色拥有不同的权限。在 RESTful API 中,基于角色的授权的实现方式如下:

  1. 定义角色和权限的映射关系,例如:

  2. 在路由处理函数中检查用户是否拥有访问该资源的权限,例如:

在上面的示例代码中,我们定义了一个 rolePermissions 对象来映射角色和权限的关系,例如管理员拥有读、写和删除的权限,普通用户只拥有读的权限。在处理 /api/users 路由时,我们首先检查用户是否拥有读的权限,如果没有则返回 403 Forbidden 状态码,否则返回用户列表。

基于资源的授权

基于资源的授权是针对特定资源的授权方式,它将权限分配给特定的资源,而不是用户或角色。在 RESTful API 中,基于资源的授权的实现方式如下:

  1. 在路由处理函数中检查用户是否拥有访问该资源的权限,例如:

在上面的示例代码中,我们定义了一个 posts 数组来存储文章,每篇文章都有一个 author 字段来指定作者。在处理 /api/posts/:id 路由时,我们首先查找指定 id 的文章,如果没有找到则返回 404 Not found 状态码,否则检查当前用户是否是文章的作者,如果不是则返回 403 Forbidden 状态码,否则返回文章内容。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d40474a941bf713479c97c