使用Amazon Cognito实现Django登录注册认证求助
解决方案:Django + Amazon Cognito 认证配置指南
一、基础配置修正
先确保settings.py中的Cognito与DRF配置完全正确,替换占位符为你的AWS实际信息:
# settings.py INSTALLED_APPS = [ # 保留默认Django APP 'rest_framework', ] REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'django_cognito_jwt.JSONWebTokenAuthentication', # 保留Session认证用于Django后台管理 'rest_framework.authentication.SessionAuthentication', ], 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', ] } # Cognito核心配置 COGNITO_AWS_REGION = '你的AWS区域(如us-east-1)' COGNITO_USER_POOL = '你的用户池ID' COGNITO_APP_CLIENT_ID = '你的应用客户端ID' COGNITO_JWT_ALGORITHM = 'RS256' # 手动指定JWKS端点,避免旧版本库的硬编码问题 COGNITO_JWKS_ENDPOINT = f'https://cognito-idp.{COGNITO_AWS_REGION}.amazonaws.com/{COGNITO_USER_POOL}/.well-known/jwks.json'
二、django-cognito-jwt 常见问题排查
由于你使用的django-cognito-jwt==0.0.4版本较旧,与Django4.1.7存在兼容性坑,针对性修复:
1. 用户同步逻辑修复
旧版本默认创建Django用户时可能缺失字段同步,自定义认证后端补全:
# 在你的app下创建backends.py from django_cognito_jwt.backends import CognitoJWTAuthenticationBackend class CustomCognitoBackend(CognitoJWTAuthenticationBackend): def authenticate(self, request, token=None): user = super().authenticate(request, token) if user and token: # 同步Cognito用户的邮箱验证状态到Django用户 user.is_active = token.get('email_verified', True) user.email = token.get('email', user.email) user.save() return user
然后在settings.py更新认证后端:
AUTHENTICATION_BACKENDS = [ 'your_app.backends.CustomCognitoBackend', 'django.contrib.auth.backends.ModelBackend', ]
2. 版本兼容补丁
如果遇到import_string相关报错,找到django_cognito_jwt/backends.py,将导入语句修改为:
from django.utils.module_loading import import_string
三、注册流程实现
django-cognito-jwt不处理注册,用boto3调用Cognito API实现:
- 安装依赖:
pip install boto3
- 编写注册视图:
# views.py import boto3 from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status from django.conf import settings class CognitoRegisterView(APIView): def post(self, request): username = request.data.get('username') password = request.data.get('password') email = request.data.get('email') if not all([username, password, email]): return Response({'error': '用户名、密码、邮箱为必填项'}, status=status.HTTP_400_BAD_REQUEST) client = boto3.client('cognito-idp', region_name=settings.COGNITO_AWS_REGION) try: client.sign_up( ClientId=settings.COGNITO_APP_CLIENT_ID, Username=username, Password=password, UserAttributes=[{'Name': 'email', 'Value': email}] ) # 若用户池开启自动验证,可取消注释以下代码 # client.admin_confirm_sign_up( # UserPoolId=settings.COGNITO_USER_POOL, # Username=username # ) return Response({'message': '注册成功,请查收邮箱验证链接'}, status=status.HTTP_201_CREATED) except client.exceptions.UsernameExistsException: return Response({'error': '该用户名已存在'}, status=status.HTTP_400_BAD_REQUEST) except Exception as e: return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST)
- 配置注册URL:
# urls.py from django.urls import path from .views import CognitoRegisterView urlpatterns = [ # 其他URL path('register/', CognitoRegisterView.as_view(), name='cognito-register'), ]
四、登录验证测试
前端调用Cognito的initiate_auth接口获取JWT令牌后,在请求Django API时,将令牌放在Authorization头中,格式为Bearer <JWT_TOKEN>。编写测试视图验证:
# views.py from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated class TestAuthView(APIView): permission_classes = [IsAuthenticated] def get(self, request): return Response({ 'message': '认证成功', 'username': request.user.username, 'email': request.user.email })
内容的提问来源于stack exchange,提问作者Honey Anand2
相关产品推荐
相关产品推荐

