📜  在 django 中创建 jwt 令牌 - Python (1)

📅  最后修改于: 2023-12-03 15:37:19.592000             🧑  作者: Mango

在 Django 中创建 JWT 令牌 - Python

随着Web应用程序的日益普及,向网站提供的敏感信息和服务越来越多。对于这些服务,我们需要一种安全的方法来验证用户身份。JWT(JSON Web Token)是一种安全的方法,用于验证用户身份,并且在Django中创建JWT令牌非常简单。

什么是JWT

JSON Web Token(JWT)是一种安全的方法,用于在两个实体之间加密交换信息。这两个实体可以是客户端和服务器,两个服务器之间,以及其他组合。

JWT使用JSON格式存储信息。通过这种方法,就可以使用多种编程语言编写编码和解码算法,以验证JWT是否有效。

JWT令牌由3个部分组成 - 标头,声明和签名,每个部分都使用点分隔符分开。JWT令牌使用Base64编码,但不是加密。

安装PyJWT

在Django中创建JWT令牌需要使用PyJWT库。您可以使用pip安装:

pip install PyJWT
创建JWT令牌

首先,您需要在settings.py文件中设置SECRET_KEY:

SECRET_KEY = 'my_secret_key'

在您的views.py文件中创建JWT令牌:

import jwt
from datetime import datetime, timedelta
from django.conf import settings
from django.contrib.auth.models import User
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import AllowAny

class JWTView(APIView):
    permission_classes = [AllowAny]

    def post(self, request):
        username = request.data.get('username')
        password = request.data.get('password')

        user = User.objects.filter(username=username).first()
        if user is None:
            return Response({'error': 'Invalid Credentials'})
        
        if not user.check_password(password):
            return Response({'error': 'Invalid Credentials'})

        payload = {
            'user_id': user.id,
            'exp': datetime.utcnow() + timedelta(minutes=60),
            'iat': datetime.utcnow()
        }

        token = jwt.encode(payload, settings.SECRET_KEY, algorithm='HS256')

        return Response({'token': token})

在这个视图中,我们先验证用户输入的凭据。然后,使用用户ID,有效期和签发时间创建JWT荷载。最后,使用jwt.encode()方法创建JWT令牌。

验证JWT令牌

在您的views.py中验证JWT令牌:

import jwt
from django.conf import settings
from django.http import JsonResponse
from rest_framework.decorators import api_view

@api_view(['GET'])
def protected(request):
    token = request.META.get('HTTP_AUTHORIZATION')
    if not token:
        return JsonResponse({'error': 'Token is missing.'}, status=400)

    try:
        payload = jwt.decode(token.encode('utf-8'), settings.SECRET_KEY, algorithms=['HS256'])
        user_id = payload.get('user_id')
        user = User.objects.filter(id=user_id).first()
        
        if user is None:
            return JsonResponse({'error': 'Invalid token'}, status=400)
            
        return JsonResponse({'message': 'Success!'})
    except jwt.ExpiredSignatureError:
        return JsonResponse({'error': 'Token has expired.'}, status=400)
    except jwt.InvalidTokenError:
        return JsonResponse({'error': 'Invalid token.'}, status=400)

在此视图中,我们首先从HTTP Headers中获取JWT令牌。然后,使用jwt.decode()方法对JWT令牌进行解码。如果JWT签名无效或过期,则引发异常。我们检查解码的负载,找到与特定用户ID相对应的用户。如果未找到用户,则返回错误消息。否则,我们将返回成功消息。

结论

在Django中使用PyJWT创建JWT令牌非常简单。通过设置“SECRET_KEY”和使用jwt.encode()和jwt.decode()方法,您可以利用JWT提供的安全性。在将来,非常有用的是,您可以将其他信息添加到“负载”中,例如用户权限和其他关键数据。