使用TOTP实现双因素认证时用户名密码为字节类型报错咨询
问题解决方法
核心原因
Django 原生 authenticate 身份校验接口要求传入的 username、password 参数均为字符串类型,你当前代码主动对两个参数做了UTF-8编码转字节操作,是导致校验失败的直接原因。
修复步骤
- 删除
login_view函数中多余的编码转换代码,保留原始字符串即可,同时修正代码中存在的语法、逻辑问题:
修正后的login_view代码如下:
def login_view(request): if request.user.is_authenticated: return redirect('/dashboard') if request.method == 'POST': email = request.POST['email'] password = request.POST['password'] fact = User.objects.filter(email=email).values('username') # 补充空值判断避免查询不到数据时报索引错误 if not fact.exists(): context = {'error':'incorrect username or password'} return render(request, 'index.html' , context) username = fact[0]['username'] # 直接传入字符串参数做校验,无需转字节 user = authenticate(request, username=username, password=password) if user is None: context = {'error':'incorrect username or password'} return render(request, 'index.html' , context) is_enrolled = enrolled(request) if not is_enrolled.json(): login(request, user) return redirect('/dashboard') return render(request, 'tokenlogin.html') return render(request, 'index.html')
- 修正
enrolled函数缺少返回值的问题:
def enrolled(request): email = request.POST['email'] res = requests.post( 'http://0.0.0.0:8000/api/users/email/', data={ 'account_name': email, }, headers={ 'Authorization': 'Bearer {0}'.format(ACCESS_TOKEN), 'Content-Type': 'application/x-www-form-urlencoded' } ) # 补充返回值,否则调用json方法会报错 return res
其他注意事项
- 不要使用全局缓存存储单个用户的
email、user信息,多用户同时登录时会出现身份串号的严重安全问题 isenrolled和enrolled两个函数功能高度重复,建议根据使用场景合并优化,减少冗余代码- 调用外部校验接口时建议加异常捕获,避免接口不可用时直接导致登录功能崩溃
内容的提问来源于stack exchange,提问作者destro164
相关产品推荐
相关产品推荐

