Django Ninja与JWT集成:构建无状态认证系统

Django Ninja与JWT集成:构建无状态认证系统

【免费下载链接】django-ninja 💨 Fast, Async-ready, Openapi, type hints based framework for building APIs 【免费下载链接】django-ninja 项目地址: https://gitcode.com/gh_mirrors/dj/django-ninja

在现代Web应用开发中,无状态认证已成为API安全的标准方案。Django Ninja作为基于类型提示的高性能API框架,通过灵活的扩展机制支持JWT(JSON Web Token)认证。本文将详细介绍如何在Django Ninja项目中实现完整的JWT认证流程,包括令牌生成、验证、刷新和权限控制。

认证系统核心组件

Django Ninja的认证系统基于HttpBearer抽象类实现,位于ninja/security/http.py文件中。该类定义了Bearer令牌的基础验证逻辑,通过继承该类可快速实现JWT验证机制。

基础架构

from ninja.security import HttpBearer

class AuthBearer(HttpBearer):
    def authenticate(self, request, token):
        # 此处实现JWT验证逻辑
        if self.verify_jwt(token):
            return token
        raise InvalidToken

上述代码展示了JWT认证的核心架构,通过重写authenticate方法实现自定义验证逻辑。Django Ninja官方提供了Bearer认证示例代码,可参考docs/src/tutorial/authentication/bearer02.py

实现JWT认证流程

1. 安装依赖

JWT认证需要PyJWT库支持,通过以下命令安装:

pip install PyJWT

2. 创建JWT工具类

在项目中创建JWT工具模块,实现令牌生成与验证功能:

import jwt
from datetime import datetime, timedelta
from django.conf import settings

class JWTUtils:
    @staticmethod
    def generate_token(user_id):
        payload = {
            'user_id': user_id,
            'exp': datetime.utcnow() + timedelta(hours=1)
        }
        return jwt.encode(payload, settings.SECRET_KEY, algorithm='HS256')
    
    @staticmethod
    def verify_token(token):
        try:
            payload = jwt.decode(token, settings.SECRET_KEY, algorithms=['HS256'])
            return payload['user_id']
        except jwt.ExpiredSignatureError:
            raise InvalidToken("Token expired")
        except jwt.InvalidTokenError:
            raise InvalidToken("Invalid token")

3. 实现认证后端

结合JWT工具类与Django Ninja的认证系统:

from ninja.security import HttpBearer
from .jwt_utils import JWTUtils

class JWTAuth(HttpBearer):
    def authenticate(self, request, token):
        try:
            user_id = JWTUtils.verify_token(token)
            # 可在此处从数据库获取用户对象
            return {"user_id": user_id}
        except Exception as e:
            return None

集成到API端点

基本使用方式

将JWT认证应用到API路由:

from ninja import NinjaAPI
from .auth import JWTAuth

api = NinjaAPI()
auth = JWTAuth()

@api.get("/protected", auth=auth)
def protected_route(request):
    return {"user_id": request.auth["user_id"]}

令牌生成端点

创建登录接口用于生成JWT令牌:

@api.post("/login")
def login(request, username: str, password: str):
    # 此处实现用户验证逻辑
    user = authenticate(username=username, password=password)
    if user:
        token = JWTUtils.generate_token(user.id)
        return {"access_token": token, "token_type": "bearer"}
    return {"detail": "Invalid credentials"}, 401

认证流程可视化

JWT认证流程包含三个主要步骤:登录获取令牌、使用令牌访问受保护资源、令牌过期处理。

JWT认证流程

图:Django Ninja Swagger UI中的认证交互界面

在Swagger UI中测试认证接口时,需点击"Authorize"按钮并输入Bearer令牌,如docs/img/auth-swagger-ui-prompt.png所示。

高级应用

全局认证配置

可通过API初始化参数设置全局认证:

api = NinjaAPI(auth=JWTAuth())

# 无需单独指定auth参数
@api.get("/global-protected")
def global_protected(request):
    return {"user_id": request.auth["user_id"]}

令牌刷新机制

实现令牌刷新端点避免频繁登录:

@api.post("/refresh-token")
def refresh_token(request, token: str):
    try:
        payload = jwt.decode(token, settings.SECRET_KEY, algorithms=['HS256'], options={"verify_signature": True, "verify_exp": False})
        new_token = JWTUtils.generate_token(payload['user_id'])
        return {"access_token": new_token}
    except:
        return {"detail": "Invalid token"}, 401

测试与验证

使用测试客户端

Django Ninja提供了测试客户端用于验证认证功能:

from ninja.testing import TestClient
from .api import api

client = TestClient(api)

def test_protected_route():
    token = "valid_jwt_token_here"
    response = client.get("/protected", headers={"Authorization": f"Bearer {token}"})
    assert response.status_code == 200

完整的测试用例可参考项目测试代码tests/test_auth.py

总结

通过Django Ninja的HttpBearer认证框架,结合JWT实现无状态认证系统仅需少量代码。这种方案具有以下优势:

  1. 无状态设计:服务器无需存储会话信息,易于水平扩展
  2. 安全可靠:基于加密签名机制,防止令牌篡改
  3. 易于集成:与Django Ninja的类型提示系统完美结合
  4. 自动文档:Swagger UI自动生成认证相关文档

官方文档提供了更多认证相关内容,包括多认证策略、权限控制等高级主题,可参考docs/guides/authentication.md

【免费下载链接】django-ninja 💨 Fast, Async-ready, Openapi, type hints based framework for building APIs 【免费下载链接】django-ninja 项目地址: https://gitcode.com/gh_mirrors/dj/django-ninja

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值