1.开发环境:
操作系统:Windows 10
编译工具:Visual Studio Code (python)+ Webstorm(html)
服务器: Django 内置测试服务器
开发语言: python 3.5.2
框架:Django 1.10.7
数据库:mysql
2.文件目录结构:
1.个人博客项目:
- Business ----------- //项目工程名
- blogApp ----------- //应用程序
+ __pycache__
+ migrations
- static ----------- //静态文件
+ bootstrap
+ fonts
+ img
+ js
+ sass
- templates ----------- //模板文件 ( T )
- index
Login_.html //登录页面
login_index.html //登录首页
article.html
article_add.html
base.html
bin.html
reseting.html
user.html
__init__.py
admin.py //后台
apps.py
models.py //模型 ( M )
tests.py
view.py //视图 ( V )
- Myblog
+ _pycache_
__init__.py
setting.py //配置
urls.py //链接
view.py //主视图
wsgi.py
manage.py //主管理文件
2.Django官方文档投票程序:
- MyBlog
- MyBlog //应用程序
+ __pycache__
__init__.py
setting.py
urls.py
wsgi.py
- polls
+ __pycache__
+ migrations
- templates
- polls
detail.html
index.html
results.html
__init__.py
admin.py
apps.py
models.py
tests.py
urls.py
views.py
3. 问题详情:
(1)个人博客项目Django CSRF保护机制:
CSRF原理:
CSRF定义:
Cross-site request forgery 即跨站请求伪造。
过程:
1. 用户C访问存在CSRF漏洞的Web A,输入用户名与密码请求登录。
2.Web A 产生Cookies信息并返回浏览器,用户C登录成功,正常访问Web A。
3.用户C未退出Web A 站点,在同一浏览器中,打开一个访问Web B的Tab页。
4.用户C第二次请求Web B。
5.Web B 返回恶意代码。
6.Web B 获得用户C Cookies信息后,带着用户C Cookies信息访问 Web A
Django中的CSRF防御方法论:
1.在请求中添加Token值,Token是一个随机数。
2.响应并验证Token,验证通过正常登录,验证失败返回403错误,如下:
错误:
Forbidden (403)
CSRF verification failed. Request aborted.
Reason given for failure:
CSRF cookie not set.
原代码:
#urls.py主要urls
urlpatterns=[
url(r'^login/',login,name='login'),
url(r'^login_in/$',login_in,name='login_in'),
]
#views.py视图
deflogin(request):
returnrender_to_response('index/login_.html')
deflogin_in(request):
username=User.objects.get(username=request.POST['username'])
ifusername.password==request.POST['password']:
request.session['user_id']=username.id
returnrender_to_response('index/login_index.html',)
#models.py模型
classUser(models.Model):
username=models.CharField(max_length=50)
password=models.CharField(max_length=50)
classArticle(models.Model):
title=models.CharField(max_length=100)
content=models.CharField(max_length=5000)
date=models.DateTimeField(auto_now=True)
#templates模板目录
#login_.html
{%csrf_token%}
博客登录系统
用户名:
密码:
登录
新代码:
# urls.py主要的urls
urlpatterns=[
url(r'^login/',include('blogApp.urls')),
]
#urls.py二级Urls
urlpatterns=[
url(r'^$',login,name='login'),
url(r'^login_index/$',login_index,name='login_index')
]
#views.py
deflogin(request):
returnrender(request,'index/login_.html')
deflogin_index(request):
username=User.objects.get(username=request.POST['username'])
ifusername.password==request.POST['password']
:
request.session['user_id']=username.id
returnrender(request,'index/login_index.html',)
# templates
#login_.html
{%csrf_token%}
博客登录系统
用户名:
密码:
登录
原代码与新代码:
区别:
1.原代码通过urls.py文件里的url访问相对应的视图函数。即当输入http://localhost:8000/login/调用urls.py里的login函数,login函数响应模板login.html并返回login.html给浏览器从而展现login.html。当完成用户名与密码的输入,点击“登录”,form表单根据action值(/login_in/)访问视图login_in函数,此时提交的form表单的Token值服务器并未获取到,验证失败进而显示403错误。原因很简单url地址不同,如:
http://localhost:8000/login/直接跳转到http://localhost:8000/login_in/;
2.新代码运行的效果:http://localhost:8000/login/跳转到http://localhost:8000/login/login_index/ 前者直接换了url地址login_index 没有获取到Token值 后者获取到Token值,从而登录成功。(个人理解 )这是参考官方文档投票程序的理解进而解决了个人博客登录问题。
总结:为什么会导致产生403错误,原因:没有对Django工作机制了解透彻。导致了我在403错误问题出现之后翻阅了Stack Overflow,百度,谷歌都用了还是没有解决而后我又回去翻翻官方文档并跟着教程加深理解,最终在投票应用程序中找到了类似问题并用于自己个人博客项目中,而后完美解决。(萌新前端的苦)