在现代 Web 应用程序中,认证和授权是非常重要的安全措施。Django REST Framework(DRF)是一个功能强大且灵活的工具,它可以帮助开发人员轻松地构建 RESTful API。在本文中,我们将关注 DRF 的认证和授权机制,探讨如何使用 JSON Web Token(JWT)实现这些机制。
什么是 JWT?
JSON Web Tokens(JWT)是一种开放标准(RFC 7519),它定义了用于安全地在两个实体之间传输信息的紧凑和自包含的方式。JWT 通常用于身份验证和授权,通常被用作在客户端和服务器之间传输信息的令牌。
一个 JWT 由三部分构成:
- Header:描述 JWT 的元数据,并指定签名算法。
- Payload:包含要传输的信息。
- Signature:基于 Header 和 Payload 以及秘钥生成的签名值。
JWT 的流程如下图所示:
Django REST Framework 的认证和授权机制
DRF 提供了各种认证方法和授权策略,包括 BasicAuthentication,SessionAuthentication,TokenAuthentication 等。其中,默认的认证和授权机制如下所示:
- 用户在浏览器中登录,服务器在 Session 中存储用户的信息。
- 用户在每个请求中都将 cookie 发送回服务器,服务器使用 Session 来验证用户的身份。
- 如果用户未登录,则服务器会返回 HTTP 401 Unauthorized,客户端将重定向到登录页面。
这种方法是比较简单的,但也有以下缺点:
- 无法在跨域情况下使用。
- 无法通过 API 对客户端进行身份验证。
- 无法为每个请求提供无状态身份验证机制。
因此,我们需要一种更好的方法来实现认证和授权机制。
使用 JWT 实现认证和授权
JWT 可以很好地解决上述问题,它可以提供无状态的身份验证机制,支持跨域,并且可以通过 API 进行身份验证。下面我们来看一下如何使用 JWT 实现 DRF 的认证和授权机制。
安装和配置
首先,我们需要安装 djangorestframework_simplejwt
库:
pip install djangorestframework_simplejwt
之后,我们需要将 JWT 添加到 DRF 的认证类中:
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework_simplejwt.authentication.JWTAuthentication', ], }
用户认证
用户通过登录页面进行身份验证,以获取其凭证(即用户名和密码)。凭证可以通过 POST 请求发送到服务器,如下所示:
-- -------------------- ---- ------- ---- ----------- -------- ----- ----------- ------------- ---------------- --------------- -- - ----------- -------- ----------- ------------- -
服务器验证身份成功后,将返回 JWT 令牌:
HTTP/1.1 200 OK Content-Type: application/json Content-Length: 676 { "access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." }
上面的例子中,access
表示访问令牌,refresh
表示刷新令牌。访问令牌通常用于身份验证,有效期较短,通常为 5 分钟。刷新令牌通常用于获取新的访问令牌,有效期较长,通常为 1 个月。
访问授权
当用户登录并获取访问令牌后,可以通过将令牌作为 Authorization 标头发送到 API 来访问受保护的资源,如下所示:
GET /api/me/ HTTP/1.1 Host: example.com Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
如果访问令牌有效,则服务器会响应 200 OK 并返回用户信息。如果访问令牌无效,则服务器会响应 401 Unauthorized 或 403 Forbidden。
刷新令牌
访问令牌是有限的,通常只能使用短时间。当访问令牌过期后,客户端需要使用刷新令牌来获取新的访问令牌。刷新令牌可以通过 POST 请求发送到服务器,如下所示:
-- -------------------- ---- ------- ---- ------------------- -------- ----- ----------- ------------- ---------------- --------------- -- -------------- ------ --------------------------------------- - ---------- ----------------------------------------- -
服务器验证刷新令牌成功后,将返回新的访问令牌:
HTTP/1.1 200 OK Content-Type: application/json Content-Length: 163 { "access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", }
撤销令牌
在某些情况下,例如用户更改密码或用户决定注销账户等,我们需要撤销令牌以保证安全性。DRF SimpleJWT 提供了一个视图函数来撤销 JWT,如下所示:
-- -------------------- ---- ------- ---- ------------------------------ ------ ------------------- ----- ----------------------------------------------- --- ---------- -------- ------ ---------- ---------- - -------------------------------------- ----------------------------------------- ---- - --------------------------------- ----- - --------------------- ------ -------------- ----------- - ------- ------ ---------------
对于撤销令牌,我们需要自己实现。一个简单的解决方案是在每次身份验证时检查用户 ID 是否与令牌 ID 相同。如果不同,则表示令牌已被撤销,需要重新进行身份验证。
结论
在本文中,我们介绍了 JWT,并探讨了如何使用 DRF SimpleJWT 库将 JWT 集成到 DRF 中,以实现更安全且可扩展的认证和授权机制。最后,我们也提到了一些关于 JWT 的使用技巧和最佳实践,例如令牌刷新、令牌撤销等。希望这篇文章对你有所帮助!
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/670a192ad91dce0dc87eadce