You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 10:35:16