Django项目中使用JWT身份验证
一、什么是JWT
JWT,全称是JSON Web Token,是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于在多方之间安全地传输JSON格式的信息。这些信息可以被验证和信任,因为它们是数字签名的。JWT由三部分组成:头部(Header)、负载(Payload)、签名(Signature),每部分之间以.
分隔。
JWT最常见的使用场景是缓存当前用户登录信息,用于认证和数据交换。在用户注册或登录后,JWT可以用来记录用户的登录状态或为用户创建身份认证的凭证。当用户登录成功之后,服务器会发放一个JWT给客户端,客户端之后的每一个请求在请求头携带上Authorization字段,以此来辨别区分请求的用户信息。
此外,JWT还支持使用HMAC算法或者是RSA的公私密钥对进行签名,因此它可以被用于安全地传递信息。由于JWT的这些特性,它特别适用于分布式站点的单点登录(SSO)场景,以及在网络应用环境间传递声明时执行基于JSON的开放标准。
二、JWT(JSON Web Token)身份验证的实现过程
- 用户登录:客户端(如Web浏览器或移动应用)发送用户名和密码到服务器进行登录请求。这一过程通常通过HTTPS协议进行,以确保信息传输的安全性。
- 服务器验证:服务器收到登录请求后,会核对用户名和密码。如果验证成功,服务器将生成一个JWT。这个JWT包含用户的一些信息(如用户ID等)和一个有效期。此外,JWT还包含一些其他的信息,如发行者、受众、签名算法等。
- 签发JWT:服务器将JWT的负载(Payload)和头部(Header)分别进行Base64编码,然后将它们拼接在一起,并使用一个密钥进行签名。这个签名用于验证JWT的真实性和完整性。最后,服务器将编码后的JWT返回给客户端。
- 客户端存储JWT:客户端收到JWT后,通常会将其存储在本地,如localStorage或sessionStorage。这样,在后续的请求中,客户端就可以使用这个JWT来证明自己的身份。
- 发送请求:当客户端需要向服务器发送请求时,它会在请求头中的Authorization字段中添加JWT。这样,服务器就能知道这个请求是来自哪个用户。
- 服务器验证JWT:服务器收到请求后,会提取出JWT,并验证其签名和有效期。如果验证通过,服务器就会处理这个请求,否则,它会拒绝这个请求。
- 处理请求:如果JWT验证通过,服务器会根据JWT中的用户信息来执行相应的操作,如查询数据库、更新数据等,然后返回结果给客户端。
这就是JWT身份验证的基本实现过程。通过使用JWT,服务器可以方便地验证用户的身份,并控制用户对资源的访问权限。同时,由于JWT是存储在客户端的,所以它可以减少服务器的存储压力,提高系统的性能。
三、JWT(JSON Web Token)的格式
JWT(JSON Web Token)的格式通常由三部分组成,它们由点(.)分隔。这三部分分别是:
-
Header(头部):头部通常包含JWT的类型(即JWT)和所使用的签名算法(如HMAC SHA256或RSA)。这部分使用Base64Url编码。
-
Payload(负载):负载包含声明(Claims),这些声明是关于实体(通常是用户)和其他数据的声明。声明是JWT的主体内容,可以包含各种信息,如用户ID、用户名、角色、过期时间等。这些声明也使用Base64Url编码。
-
Signature(签名):签名是对头部和负载的签名,以确保JWT的真实性和完整性。签名使用在头部中指定的签名算法和密钥进行生成。
因此,一个典型的JWT格式如下: <Base64Url(Header)>.<Base64Url(Payload)>.<Signature> 例如: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.e3M-sJf6w25w5z0e_S2dQ7qM8OAPeJ65XkZ22-Y4eM
四、Django使用JWT身份验证
在Django中,可以使用第三方库如 django-rest-framework-jwt
或 PyJWT
来实现 JWT 认证。以下是如何在Django项目中使用 JWT 的基本步骤:
-
安装第三方库:
首先,你需要安装支持 JWT 的库。对于 Django REST framework,你可以使用django-rest-framework-jwt
。pip install djangorestframework-jwt
-
配置 JWT:
在你的 Django 项目的设置文件(settings.py
)中,你需要添加 JWT 的配置。INSTALLED_APPS = [ # ... 'rest_framework', 'rest_framework_jwt', # ... ] REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', # ... other authentication classes ], } JWT_AUTH = { 'JWT_SECRET_KEY': 'your-secret-key', # Should be a random string 'JWT_GET_USER_SECRET_KEY': None, 'JWT_PUBLIC_KEY': None, 'JWT_PRIVATE_KEY': None, 'JWT_ALGORITHM': 'HS256', 'JWT_ALLOW_REFRESH': True, # ... other configurations }
3.创建和验证 Tokens:
使用django-rest-framework-jwt
提供的视图,你可以很容易地创建和验证 JWT。
from rest_framework_jwt.views import obtain_jwt_token
# Obtain the token
token = obtain_jwt_token(request)
为了验证 token,你可以使用 django-rest-framework-jwt
提供的装饰器或中间件。
4.自定义 Token 生成和验证:
如果你需要更细粒度的控制,可以自定义 token 的生成和验证过程。PyJWT
库可以帮助你手动生成和验证 tokens。
5.保护你的 API 端点:
一旦配置了 JWT 认证,你可以使用 Django REST framework 的权限类来确保只有经过验证的用户才能访问特定的 API 端点。
from rest_framework.permissions import IsAuthenticated
class MyView(APIView):
permission_classes = [IsAuthenticated]
def get(self, request, format=None):
# Only authenticated users can access this endpoint
content = {"message": "Hello, you're authenticated!"}
return Response(content)
6.处理用户登录和注销:
你需要实现用户登录和注销的逻辑,以便在用户成功登录时生成 token,并在用户注销时使其失效。