CSRF跨域请求保护
A站为正常网站,B站为病毒网站,当我先访问A站,本地浏览器会记录cookies
在本地,之后访问B站,B站会窃取我的cookies
,然后通过我的cookies
就可以冒名访问A站中我的账户。这就是CSRF
跨站请求伪造攻击。
在Django
的form
表单提交时,如果是POST
方法提交,会引发CSRF
跨域请求保护,解决方法为:在form
表单中添加{% csrf_token %}
,打开网站就会在页面生成token
(令牌)来进行认证,当别人登录会,页面会生成完全不一样的token
,登录时抓包会发现提交的form
表单中会有csrfmiddlewaretoken
这么一项。
HTML 的登录表单
登录功能的实现
当点击登录时,会将表单提交到urls.py
中的别名为login
的url
来处理,如:
...
urlpatterns = [
...
url(r'^login/', views.login_site, name='login'),
url(r'^logout/', views.logout_site, name='logout'),
]
处理逻辑为:如果方式为Post
,获取到提交的username
和password
,然后通过django
的authenticate
方法来验证。
# 导入的login 和 logout 用来实现保持session
from django.contrib.auth import authenticate, login, logout
def login_site(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(username=username, password=password) # 使用 Django 的 authenticate 方法来验证
if user:
login(request, user) # <==
return HttpResponseRedirect('/')
else:
return render(request, 'login.html', {
'login_err': 'Please recheck your username or password !'
})
return render(request, 'login.html')
登出功能
def logout_site(request):
logout(request) # <==
return HttpResponseRedirect('/')
HTML 页面验证是否登录
页面中需要根据是否登录来显示登录状态,登录显示登录的用户名,未登录显示login
...
...
强制登录
网站很多页面我们需要用户登录才能展示,或者说打开网站时,必须先登录。可以进行如下两步设置:
第一步:在settings.py
文件中写明当用户未登录就访问网站时的跳转路径。
# settings.py 文件中
LOGIN_URL = '/login/'
第二步:在需要登录才能打开的页面中使用login_required
装饰器
from django.contrib.auth.decorators import login_required
@login_required
def dashboard(request):
return render(request, 'dashboard.html')
...
...