Django 之login_required的知识点
Django 之login_required的知识点
在进行页面登录验证优化时,想到了用户验证登录和登出及限流功能,在添加用户登录调用@login_required时,访问/login自动跳转到/accounts/login/,这个路由又没有定义就是显示404状态码。
作为一个新入门的学习者首先是排查路由配置、视图、去掉验证@login_required验证发现是@login_required的跳转定义问题,在没有定义的情况下默认跳转路径就是/accounts/login/,这下就破案了。
接下来,就是找解决方案,搜一下@login_required验证失败重定向的配置即可。
路由配置
from django.contrib import admin from django.urls import path, include from myapp.views import * urlpatterns = [ path('admin/', admin.site.urls), path('login/', login_view, name='login'), path('logout/', user_logout, name='logout'), path('captcha/', include('captcha.urls')), path('upload/', upload_file, name='upload'), ]
视图配置
from django.contrib import messages from captcha.models import CaptchaStore from captcha.helpers import captcha_image_url from django.shortcuts import redirect #添加用户登录视图和注销视图: from django.contrib.auth.decorators import login_required from django.contrib.auth import authenticate, login, logout import paramiko import tempfile def login_view(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') captcha_solution = request.POST.get('captcha_solution') captcha_key = request.POST.get('captcha_key') # 验证码校验 if captcha_key and captcha_solution: if not CaptchaStore.objects.filter(response=captcha_solution, hashkey=captcha_key).exists(): messages.error(request, '验证码错误') return redirect('login') # 身份验证 user = authenticate(request, username=username, password=password) if user: login(request, user) return redirect('upload') else: messages.error(request, '用户名或密码错误') return redirect('login') new_key = CaptchaStore.generate_key() image_url = captcha_image_url(new_key) return render(request, 'login.html', {'key': new_key, 'image_url': image_url}) @login_required def user_logout(request): logout(request) messages.info(request,'退出登录') return redirect('login') #定义限流装饰器 from django.core.cache import cache from django.http import HttpResponseForbidden def rate_limit(limit_count): def decorator(view_func): def wrapper(request, *args, **kwargs): # 获取当前用户 user = request.user # 检查该用户的访问次数 cache_key = f'rate_limit:{user.username}' access_count = cache.get(cache_key, 0) # 如果访问次数超过限制,返回 403 Forbidden if access_count >= limit_count: # logging.error('用户 {} 查看上传文件列表失败'.format(request.user.username, datetime.now())) return HttpResponseForbidden('访问次数超过限制') # 增加访问次数并设置缓存时间为 1 分钟 cache.set(cache_key, access_count + 1, 60) # 继续执行视图函数 return view_func(request, *args, **kwargs) return wrapper return decorator #上传视图 @login_required def upload_file(request): if request.method == 'POST': file = request.FILES.get('file') if file: # 连接远程服务器 ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # ssh.connect('remote_server_ip', username='username', password='password') ssh.connect('10.0.0.127', username='root', password='123456') try: # 创建临时文件 with tempfile.NamedTemporaryFile(delete=False) as temp_file: # 将上传的文件内容写入临时文件 for chunk in file.chunks(): temp_file.write(chunk) temp_file.seek(0) # 将文件指针移动到文件开头 # 上传临时文件到远程服务器的/data目录 sftp = ssh.open_sftp() #使用用户密码/秘钥连接 sftp.putfo(temp_file, '/home/yunwei/apache-jmeter-5.5/ProCase/scrpit/' + file.name) sftp.close() ssh.close() messages.success(request, '文件上传成功') return redirect('upload') # 重定向到上传页面 except Exception as e: messages.error(request, '文件上传失败:{}'.format(str(e))) else: messages.error(request, '请选择要上传的文件') return render(request, 'upload.html')
解决方案
在Django中,可以使用login_required装饰器来对视图函数进行登录验证。当用户没有登录时,装饰器会将用户重定向到默认的登录页面或者自定义的登录页面。
默认情况下,Django的login_required装饰器会将用户重定向到名为/accounts/login/的URL。如果你希望自定义登录跳转的URL,你可以在项目中进行相关配置。
首先,你需要在项目的URL配置文件(通常是urls.py)中定义一个URL来处理登录验证失败重定向的请求
from django.urls import path from django.contrib.auth.views import LoginView urlpatterns = [ path('my-login/', LoginView.as_view(), name='my_login'), # other URLs ]
my-login/路由将被用于处理登录验证失败的跳转请求。LoginView是Django内置的登录视图,它会自动渲染一个登录页面。
接下来,你需要告诉Django在登录验证失败时应该重定向到哪个URL。你可以在项目的设置文件(通常是settings.py)中添加以下配置:
LOGIN_URL = '/my-login/'
在这个配置中,LOGIN_URL设置为/my-login/,即登录验证失败时应该重定向到my-login/路由。
通过以上配置,当使用login_required装饰器的视图函数登录验证失败时,用户将被重定向到my-login/路由,即自定义的登录页面。
请注意,login_required装饰器需要和Django的认证系统一起工作。你需要在项目中启用认证系统并配置相关认证后端和用户模型。
访问验证