Django REST框架登录OTP验证时otp字段为None问题求助
问题修复方案
e_mail.otp返回None的核心原因是OTP生成后没有被写入用户表的otp字段,同时你的代码还存在变量名不匹配的隐含错误,按以下步骤修改即可恢复功能:
1. 修复SendOTP接口的存储逻辑
你当前的SendOTP接口生成OTP后仅更新了count计数,没有把生成的OTP值存入用户对象,修改后代码如下:
class SendOTP(APIView): permission_classes = (AllowAny, ) def post(self, request, *args, **kwargs): email = request.data.get('email') if email: email = str(email) user = User.objects.filter(email__iexact = email) if user.exists(): key = send_otp(email) if key: old = user.first() # 新增逻辑:把生成的OTP存入用户的otp字段 old.otp = key old.count = old.count + 1 old.save() print('Count Increase', old.count, 'OTP saved:', key) return Response({ 'status': True, 'detail': 'OTP sent successfully.' })
2. 修复ValidateOTP接口的变量错误
你在该接口中将用户对象赋值给了e_mail变量,但后续逻辑中使用了未定义的old变量,会直接触发报错,修改后代码如下:
class ValidateOTP(APIView): permission_classes = (AllowAny, ) def post(self, request, *args, **kwargs): email = request.data.get('email' , False) otp_sent = request.data.get('otp', False) if email and otp_sent: user = User.objects.filter(email__iexact = email) if user.exists(): user = user.first() otp = user.otp print(otp, user, otp_sent) if str(otp_sent) == str(otp): # 替换未定义的old变量为当前用户对象 user.validated = True user.save() try: payload = JWT_PAYLOAD_HANDLER(user) jwt_token = JWT_ENCODE_HANDLER(payload) update_last_login(None, user) except User.DoesNotExist: raise serializers.ValidationError( '用户不存在' ) return Response({ 'status' : True, 'email': email, 'token': jwt_token, 'detail' : 'OTP验证通过' }) else: return Response({ 'status' : False, 'detail' : 'OTP错误' }) else: return Response({ 'status' : False, 'detail' : '请先请求发送OTP' }) else: return Response({ 'status' : False, 'detail' : '请同时提供邮箱和OTP进行验证' })
可选优化建议
- 目前
send_otp函数仅生成了OTP值,没有补充实际的邮件发送逻辑,需要补上对应逻辑用户才能收到OTP - 可以给OTP增加过期时间字段,避免OTP永久有效带来的安全风险
- 验证成功后可以清空用户表的otp字段,避免同一个OTP被多次复用
内容的提问来源于stack exchange,提问作者JohnTerry
相关产品推荐
相关产品推荐

