【问题标题】:Django customized authentication Session bugDjango自定义认证Session bug
【发布时间】:2023-02-16 18:41:43
【问题描述】:

我正在使用我自定义的身份验证构建一个 Django 项目,我遇到了一个问题,用户可以绕过我的登录并通过简单地键入 URL 进入主页 像这样:“127.0.0.1/account/Adam”,“127.0.0.1/account/Bob”,“127.0.0.1/account/Alice” ,那些人没有在数据库中注册,但他们收到“欢迎亚当”、“欢迎鲍勃”、“欢迎爱丽丝” 我一直在尝试添加一个名为Auth = False 的全局变量的不同方法,一旦在数据库中找到用户并且密码匹配,Auth 将收到 True,这有点解决了我的问题,但并不像预期的那样,因为一旦该变量变为@ 987654325@ 例子:

如果 bob 已在数据库中注册并且已成功登录,则 Bob 可以在同一会话中键入这些 url 并操作最后一个 url 参数并获得 Welcome sam,Welcome Alfred ....

from django.http import HttpResponse
from django.contrib import messages
from django.contrib.auth.models import auth
from users.models import Composter
from django.core.exceptions import ObjectDoesNotExist


class MyView():
    Vuser = None


# Create your views here.
def home(request):
    return render(request, 'users/home.html')


#def compost_supplier_register(request):
    return render(request, 'users/compost_supplier_register.html')

def composter_register(request):
    if request.method == 'POST':
        #extracting form data from a POST request and assigning it to variables representing a composter's name, email, password, address, state, city, and zip code.
        composterName = request.POST['Composter_Name']
        composterEmail = request.POST['Composter_Email']
        composterPassword = request.POST['Composter_Password']
        composterConfirmationPassword = request.POST['Composter_Confirmation_Password']
        composterAddress = request.POST['Composter_Address']
        composterState = request.POST['Composter_State']
        composterCity = request.POST['Composter_City']
        composterZipCode = request.POST['Composter_Zip_Code']
        if composterPassword == composterConfirmationPassword:

            #checks if the entred composter name exists in the database
            if Composter.objects.filter(composterName=composterName).exists():
                messages.info(request,'Name is Already taken !')
                return redirect('composter_register')
                
            #checks if the entred composter email exists in the database
            elif Composter.objects.filter(composterEmail = composterEmail).exists():
                messages.info(request,'Email already taken !')
                return redirect('composter_register')
            else:
                #Affect values to composter object instance
                composter = Composter(composterName = composterName ,composterEmail = composterEmail , composterPassword = composterPassword ,composterAddress = composterAddress, composterState = composterState, composterCity = composterCity ,composterZipCode = composterZipCode)
                #Save the composter instance to the database
                composter.save()
                return redirect('composter_register')
        else:
            messages.info(request,'Password is not matching !')
            return redirect('composter_register')
    else:
        return render(request, 'users/composter_register.html')

auth = False

def login(request):
    global auth
    if request.method == 'POST':
        email = request.POST['Email']
        password = request.POST['Password']
        try:
            user = Composter.objects.get(composterEmail = email)
            if(user.composterPassword == password):
                auth = True
                if auth == True:
                    return redirect('account', composterName = user.composterName)
            else:
                auth = False
                return redirect('login')
        except ObjectDoesNotExist:
            messages.info(request,'Please enter your username and password to log in')
            return redirect('login')
        
    return render(request, 'users/login.html')

def account(request, composterName):
    global auth
    if auth == False:
        return redirect('login')
    else:
        return render(request, 'users/account.html', {'composterName':composterName})

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    {% csrf_token %}
    <h1>Welcome {{composterName}}</h1>
</body>
</html>

网址.py

from django.urls import path
from . import views
urlpatterns = [ path('', views.home, name='home'),
                path('composter_register/', views.composter_register, name='composter_register'),
                path('compost_supplier_register/', views.compost_supplier_register, name='compost_supplier_register'),
                path('login/', views.login, name='login'),
                path('account/<str:composterName>', views.account, name='account')
 ]

【问题讨论】:

    标签: python django


    【解决方案1】:

    不要从头开始发明*,最好使用Django官方提供的解决方案。 您可以为受保护的 API 使用 @login_required 装饰器

    如果您想使用自己的解决方案,请在您的用户模型中创建一个新字段/列并使用它而不是使用 auth 变量。

    【讨论】: