1.session的使用
1.1Cookie
客户端浏览器上的键值对----为了做会话保持
-怎么来的? 服务端写入的---》服务端再返回的响应头中写入---》浏览器会自动取出来--》存起来
-key value 形式--》过期时间---》path---》http only。。。
-只要浏览器中有cookie,再次向当前域发送请求,都会自动携带
-携带在 请求头中得 cookie字段中
cookie:"name=lqz;age=19"
-不安全问题---》cookie中发了敏感数据---》客户能看到
-cookie设置: obj.set_cookie()
-cookie取值: request.COOKIES.get()
-清空: request.COOKIES.clear()
1.2我们需要让Cookie变得安全
敏感数据不在cookie中方法,而放在session中
-session是服务端的键值对
-session跟cookie有什么关系呢?
{111:{name:lqz,age:19,password:123},222:{name:zs,age:19,password:666}}
-把key,以cookie的形式,存到浏览器中
sessionid:111
-当前浏览器以后再发请。就会携带 过来
-我们根据带过来的cookie 111----》 从 session中取出对应的数据
1.3session的使用
必须要先迁移表---》django-session表不存在
-session存在服务端的---》默认情况下存在---》django-session表中
-配置文件
-django项目有两套配置文件:内置一套,项目自己一套
-SESSION_ENGINE = 'django.contrib.sessions.backends.db'
取值:request.session.get()
赋值:request.session['name']='lqz'
1.4django-session表的字段
session_key: sessionid:随机字符串
session_data: 真正的数据--->加密了
expire_date: 过期时间
1.5session的本质执行原理
1 咱么写了request.session['name']='lqz',本质就是向session 对象中放入了name=lqz
2 当前视图函数结束-----》经过 【中间件】 ---》返回给了前端
-django 内置了一个session中间件
-判断:request.session 有没有变化,如果有变化
- 情况一:django-session表中没有数据
在表中创建出一条数据,随机生成一个字符串[随机字符串session_key],把数据存入django-session表
session_key:adsfasd
session_data: name=lqz 加密后存到里面
把随机字符串写入到cookie中 :sessionid:adsfasd
- 情况二:django-session表中有数据
把session中所有的值--》加密后--》更新到django-session表的session_data中,其他不变
3 下次 再发请求进入任意视图函数---》又会经过 【中间件】---》视图函数
-视图函数中取session:request.session.get('age')
-浏览器发请求---》携带cookie过来---》到了中间件---》根据sessionid取出随机字符串
-拿着随机字符串去django-session中查【session_key】---》 能查到就把 session_data的数据解密---》放到request.session中
-后续视图函数中,才能取出值
'''
### session的中间件把上述内容完成了:procee_request process_response
django.contrib.sessions.middleware.SessionMiddleware
# 配置session 存放路径(未完成,需要你完成)
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
SESSION_ENGINE = 'django.contrib.sessions.backends.file'
SESSION_FILE_PATH='c://xxx/x'
SESSION_COOKIE_NAME = 'xxx'
from django.conf import settings
2.中间件
2.1简介
中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出。因为改变的是全局,所以需要谨慎实用,用不好会影响到性能
2.2作用
1 全局的请求拦截---》如果它没有登录---》就不允许访问
2 拦截所有请求,获取请求的ip地址
3 记录所有用户的访问日志
4 统一在响应头中加数据
2.3代码
# 代码上:就是一个类,类中有几个方法
process_request(self,request) # 请求来了,就会走
process_response(self, request, response) # 请求走了就会走
process_view(self, request, callback, callback_args, callback_kwargs) #视图函数执行之前调用
process_template_response(self,request,response) # 渲染模板之前会走
process_exception(self, request, exception) # 视图函数中出现异常了才执行# django内置一些中间件---》增强了djagno的功能
# request.session
# request.user
# post 请求提交数据,拦截了---》csrf认证
MIDDLEWARE = ['django.middleware.security.SecurityMiddleware',# session相关的中间件'django.contrib.sessions.middleware.SessionMiddleware',# 公共中间件---》访问不带 / 路径,如果有 带 / 的路径,他会让你重定向到这个地址'django.middleware.common.CommonMiddleware',# csrf认证 xss cors'django.middleware.csrf.CsrfViewMiddleware',# 认证:request.user--->这个中间件做的'django.contrib.auth.middleware.AuthenticationMiddleware',# django的消息框架---》flask--》闪现'django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware',
]
2.4 自定义中间件来使用,记录用户的请求地址和user-agent
class SaveRemoteAddr(MiddlewareMixin):def process_request(self, request):# request 是WSGIRequest 的对象# print(request.session) # 一定要保证,session的中间件要在上面# 这个request 就是当次请求的request# 取出ipip = request.META.get('REMOTE_ADDR')user_agent = request.META.get('HTTP_USER_AGENT')print(ip)print(user_agent)# return HttpResponse('不让你看了') # 不会再走视图函数了'''能返回的情况:1 None,表示执行完这个代码,继续往后执行---》还有中间件,继续执行--》最后进视图函数2 四件套,后续不走了,中间件的process_response---》直接返回给浏览器了'''
2.5中间件,在响应头加入访问时间
import datetime
class AddHeaderMiddleWare(MiddlewareMixin):def process_response(self, request, response):# request中有没有session? 有# request 如果在视图函数中,往request中放了值,在这里,就可以取出来 request.xxx# print(request.xxx)# 所有cookie中都带# response.set_cookie('xxxxx', 'asdfds')# 写入到响应头,访问服务端的时间response['ttt'] = datetime.datetime.now()return response # 一定要返回response对象
3.csrf认证相关
3.1csrf是什么
跨站请求伪造
3.2攻击原理
在同一个浏览器中,如果登录了A网站,没有退出,在B网站中,向A网站发送请求,浏览器会自动携带A网站的cookie,对于A网站后端来讲, 它就分辨不清到底是用户真实发的请求,还是黑客网站发的请求【都会携带用户真实的cookie】
3.3如何防范
-django解决了这个问题---》只要发送post请求,必须携带一个csrf_token 随机字符串--->后端给的-这个随机字符串可以带的位置?1 请求体中(urlencoded,form-data):{csrfmiddlewaretoken:asdfasdf}2 放在请求头中:'X-CSRFToken':asdfasdfasd3 ajax提交数据:默认是urlencoded,放在请求体中没有任何问题$.ajax({method: 'post',data: {username, password, csrfmiddlewaretoken},success: function (res) {console.log(res)}})4 ajax提交,使用json格式---》就不能放在请求体中只能放在请求头中:$.ajax({method: 'post',headers:{'X-CSRFToken':csrfmiddlewaretoken},contentType: 'application/json',data: JSON.stringify({username, password}),success: function (res) {console.log(res)}})# post 提交的数据,都是从request.POST中取,前提是:必须是urlencoded和form-data格式
# 如果是json是取不到的# 如果使用ajax发送请求redirect render就用不了了尽量使用JsonResponse
4.auth的使用
4.1简介
auth 是什么,有什么作用 auth就是django 的一个app,做用户管理
Auth模块是Django自带的用户认证模块:
我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统。此时我们需要实现包括用户注册、用户登录、用户认证、注销、修改密码等功能,这还真是个麻烦的事情呢。
Django作为一个完美主义者的终极框架,当然也会想到用户的这些痛点。它内置了强大的用户认证系统–auth,它默认使用 auth_user 表来存储用户数据
# 默认的用户表示auth_user
4.2模块的常用方法
#1 authenticate()
提供了用户认证功能,即验证用户名以及密码是否正确,一般需要username 、password两个关键字参数。
如果认证成功(用户名和密码正确有效),便会返回一个 User 对象。
authenticate()会在该 User 对象上设置一个属性来标识后端已经认证了该用户,且该信息在后续的登录过程中是需要的。
# 用法:
user = authenticate(username='usernamer',password='password')# 2 login(HttpRequest, user)
登录认证通过,调用一下这个方法,以后从request.user中才能取出当前登录用户# 3 退出,一定要调用logout(request)# 4 is_authenticated() 判断当前用户是否登录--不能使用request.user 是否有值来判断,因为他一直有值request.user.is_authenticated()