Python中Django如何更好地实现自动登录功能?

已经实现了登录,打算加入第一次登录后,下次打开网页,如果用户之前登录过,就 30 天内自动登录的功能。度娘了下,居然发现没找到比较成熟的方案。
目前的思路有两个:
1.往浏览器 cookie 中写入用户名和加密后的密码,然后后台验证。感觉这样还是有点不靠谱。
2.我自己算出一个免登录的 token,然后交给 cookie。自己建一个表,保存 token 和 user 的对应关系,还有失效时间。最后根据浏览器带过来的 token 进行登录。
对于方案 2.django 有没有已经集成相关的步骤?或者有没有什么更优雅的方式?有相关文章的,麻烦也扔过来。谢了。
Python中Django如何更好地实现自动登录功能?


9 回复

在Django里做自动登录,核心就是用django.contrib.authlogin函数配合authenticate。不过自动登录一般指的是记住登录状态,这得用session或者更持久的机制。

直接上代码吧,一个常见的实现是在登录视图里,如果用户勾选了“记住我”,就把session过期时间设长点。Django默认session过期是浏览器关闭就失效,我们可以改request.session.set_expiry()

from django.contrib.auth import authenticate, login
from django.shortcuts import render, redirect

def custom_login_view(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        remember_me = request.POST.get('remember_me')  # 假设前端有个复选框
        
        user = authenticate(request, username=username, password=password)
        
        if user is not None:
            login(request, user)
            
            if remember_me:
                # 设置session两周后过期(单位:秒)
                request.session.set_expiry(1209600)  # 14天
            else:
                # 浏览器关闭时session过期
                request.session.set_expiry(0)
                
            return redirect('home')
        else:
            # 处理认证失败
            pass
    
    return render(request, 'login.html')

更持久的自动登录(比如关掉浏览器再打开还能自动登)通常得用token存在cookie里。可以用Django的SignedCookieSessionBackend或者自己实现一个带签名的token验证。下面是个简单例子:

from django.http import HttpResponse
from django.contrib.auth.models import User
import hashlib
import time
from django.conf import settings

def generate_auto_login_token(user):
    # 生成一个简单的token(实际生产环境要用更安全的方法)
    raw_token = f"{user.id}:{user.username}:{time.time()}"
    signature = hashlib.sha256(
        f"{raw_token}:{settings.SECRET_KEY}".encode()
    ).hexdigest()
    return f"{raw_token}:{signature}"

def auto_login_from_token(request):
    token = request.COOKIES.get('auto_login_token')
    if token:
        try:
            raw_token, signature = token.rsplit(':', 1)
            expected_signature = hashlib.sha256(
                f"{raw_token}:{settings.SECRET_KEY}".encode()
            ).hexdigest()
            
            if signature == expected_signature:
                user_id, username, timestamp = raw_token.split(':')
                # 检查token是否过期(比如7天内有效)
                if time.time() - float(timestamp) < 604800:
                    user = User.objects.get(id=user_id)
                    login(request, user)
        except:
            pass
    
    return HttpResponse("Auto login attempted")

记住,自动登录有安全风险,得确保token够随机、有签名、能过期。用Django内置的session机制配合合适的过期时间通常是更安全简单的选择。

简单说就是:用session控制过期时间实现“记住我”,要更持久就用签名token。

为什么不直接延长 Session/Cookies 的有效期到 30 天?

用户登录保留长点时间没有关系,只要做好账户安全保障就可以,明明都让系统记住密码了,还要老让输入用户名密码也很烦

楼主多看书

存 redis 不就行了。。。这和 django 有什么关系

我是做客户端的,自己兴趣写点 django 的东西。是不是一般网站,点选“记住密码”的,就把 session/cookies 的时间延长?加入不点选,就默认的时间?

典型 session 不 remember me 就一小时,remember 了就比较长,我刚做一个应用改成 3 个月了

建议试试 github 的思路,平时自动登陆,敏感操作需要额外输入密码

回到顶部