Django项目基于Token的API登录认证问题求助
Django API Token认证失效问题排查与优化
我正在开发一个Django项目,为让外部工具能调用项目功能,在项目内搭建了API,但当前的Token登录认证逻辑无法正常工作,希望优化方案或指出问题所在。
用户注册时,会为其生成MD5哈希的access token,存储在与用户模型关联的AuthToken模型中,模型代码如下:
class AuthToken(models.Model): user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) token = models.TextField() created_date = models.DateField(auto_now_add=True) created_time = models.TimeField(auto_now=True) status = models.IntegerField(default=0)
当前API认证视图逻辑如下:
- 检查请求中的Token是否存在于
AuthToken表中 - 获取Token关联用户的用户名和密码
- 调用Django的
authenticate方法完成认证
我已经意识到该逻辑必然失败:从AuthToken.user.password获取的是Django加密后的密码,而authenticate方法会将传入的密码再次加密后与数据库中的密文对比,导致两次加密结果不匹配,认证失败。
当前的认证视图代码(注:代码存在重复的elif module == 'auth'分支,推测为复制错误,以下保留核心逻辑):
if module == 'auth': # authentication model queried api_token = crud # api access token token_filter = AuthToken.objects.filter(token=api_token) # filter for token existence if token_filter.count() == 1: # if there is token token_d = AuthToken.objects.get(token=api_token) username = token_d.user.username password = token_d.user.password # login user = authenticate(request, username=username, password=password) try: # check if user is valid if hasattr(user, 'is_active'): auth_login(request, user) # Redirect to a success page. return redirect('home') else: messages.error(request, f"There is an error logging in, please check your credentials again or contact " f"Administrator") return redirect('login') except Exception as e: messages.error(request, f"There was an error {e}") return redirect('login') else: return HttpResponse('INVALID TOKEN')
核心优化思路
既然已经通过Token验证了用户身份,无需再通过用户名+密码的方式调用authenticate,直接使用Token关联的用户对象完成登录即可。
优化后的认证代码
if module == 'auth': api_token = crud # 同时检查Token状态是否有效(假设status=0为有效) token_query = AuthToken.objects.filter(token=api_token, status=0).select_related('user') if token_query.exists(): token_obj = token_query.first() user = token_obj.user # 直接验证用户是否活跃 if user.is_active: auth_login(request, user) return redirect('home') else: messages.error(request, "用户账号已禁用,请联系管理员") return redirect('login') else: return HttpResponse('INVALID TOKEN')
额外优化建议
- 避免重复查询:使用
select_related('user')减少数据库查询次数,提升性能 - Token状态管理:利用
status字段区分有效/过期/禁用的Token,认证时加入状态判断 - Token过期机制:可以在
AuthToken模型中添加expire_date字段,认证时检查Token是否过期 - 替换MD5哈希:MD5安全性较低,建议使用更安全的哈希算法(如SHA-256)生成Token
- 清理冗余代码:移除重复的
elif module == 'auth'分支,减少无效代码
内容的提问来源于stack exchange,提问作者rootleet
相关产品推荐
相关产品推荐

