1.cookies与session简介
1.最早期的互联网不需要保存用户信息,所有用户哪怕之前成功登陆每次用户登录也要重新输入账号和密码。
2.cookie:保存在客户端与用户状态相关的数据,cookie是类似字典的K:V键值对。
"""
比如用户每登陆成功一次浏览器会提醒用户是否要保存用户名和密码。保存成功之后每次浏览器客户端向服务端发送用户数据,但是单纯的记录用户名和密码安全性并不高,所以早期的cookie并不好用。
而现在正在使用的是每当用户成功登陆一次,客户端都会向浏览器服务端发送一个随机字符串,每一个随机字符串对应一个用户。以后再登陆客户端只需要拿该字符串和服务端进行对比即可。
"""
3.2.session:保存在服务端与用户状态相关的数据。session需要依赖于cookie工作。
2.Django操作cookie
1.编写一个真正的用户登录系统(用户名和密码暂时写死):
def home(request):
if request.COOKIES.get('name'):
return HttpResponse('欢迎来到主页')
else:
return redirect('/login/')
def login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'max' and password == '123':
'''return返回该对象和返回重定向效果一样,此处返回对象是因为需要生成对象来传递cookie'''
obj = redirect('/home/')
obj.set_cookie('name',username)
return obj # 相当于 return redirect('/home/')
return render(request,'login.html')
此时我们哪怕直接访问路由/home/也不需要登录,因为cookie保存了我们的数据,如果删掉cookie那么需要重新登陆。
2.当前方法实现了cookie保存数据的方式,但是扩展性不强,每新增一个需要登录的功能都需要重新添加条件判断,接下来我们用装饰器来让校验功能更便捷:
def login_auth(func):
def inner(request, *args, **kwargs):
if request.COOKIES.get('name'):
'''request属于*args,可以单独拿出来,穿的时候如果只传了request首先会被形参request接收'''
res = func(request, *args, **kwargs)
return res
else:
return redirect('/login/')
return inner
@login_auth
def home1(request):
return HttpResponse('欢迎来到主页1')
@login_auth
def home2(request):
return HttpResponse('欢迎来到主页2')
@login_auth
def home(request):
return HttpResponse('欢迎来到主页')
def login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'max' and password == '123':
obj = redirect('/home/')
obj.set_cookie('name', username)
return obj
return render(request, 'login.html')
3.当前方法我们实现了多视图函数的cookie校验,但是任然有一个功能缺陷:
if username == 'max' and password == '123':
obj = redirect('/home/')
以上两行代码决定了我们不管是从哪个页面跳转过来的,登录过后我们只能跳转到/home/页面,这并不符合日常逻辑。我们采用在路由的?后面添加字符串的方式来解决该问题:
def login_auth(func):
def inner(request, *args, **kwargs):
'''request.path和request.path_info都能拿到请求页面的路由,这样我们就能记录下是哪个页面想服务端发送了请求'''
target_path = request.path_info
if request.COOKIES.get('name'):
res = func(request, *args, **kwargs)
return res
else:
'''将路由拼接在/login/?的后面,在登录界面可以将路由拿到并进行跳转'''
return redirect('/login/?next=%s'%target_path)
return inner
@login_auth
def home1(request):
return HttpResponse('欢迎来到主页1')
@login_auth
def home2(request):
return HttpResponse('欢迎来到主页2')
@login_auth
def home(request):
return HttpResponse('欢迎来到主页')
def login(request):
target_path = request.GET.get('next') # <QueryDict: {'next': ['/home1/']}>
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'max' and password == '123':
if target_path:
obj = redirect(target_path)
else:
obj = redirect('/login/')
obj.set_cookie('name', username)
return obj
return render(request, 'login.html')
3.Django操作session
1.由于session是保存在服务端上面的数据,就应该有个地方能够存储,就需要我们提前创好一张表(可以用sqlite3,也可以用mysql),但是内置的表中已经有django_session,所以我们只需要执行数据库迁移命令即可。
2.创好表之后我们继续在视图层创好相应的函数,函数体代码增加一个session数据,刷新django_session发现里面有一条加密的数据:
语法结构:request.session['key']=value
def session_func(request):
request.session['session的键'] = '今天周四,又是疯狂星期四'
return HttpResponse('session_func')
3.存数据底层发生原理:
3.1当执行request.session['key']=value之后,首先生成一个随机字符串,就是session_key
3.2对value做加密处理,django会存储session_key以及session_data的对应关系。session_data对应的就是我们添加的值'今天周四,又是疯狂星期四'。
3.3将随机字符串session_key发一份给cookie。
此后登陆服务端session会校验用户是否有该字符串,如果有的话在一定时间内就可以不用登录。
4.从session中拿数据:
语法结构:request.session.get('key')
def session_get(request):
print(request.session.get('session的键'))
return HttpResponse('session_get') # 今天周四,又是疯狂星期四
5.取数据底层发生原理:
6.1自动获取分发的随机字符串
6.2去django_session表中根据字符串获取加密的数据
6.3自动解密数据并处理到request.session.get()中
6.expire是失效时间,django默认的失效时间是两周(pycharm默认是utc时间)。超过该时间用户需要重新登陆。request.session.set_expiry(时间)。时间以秒为单位。
标签:return,request,Django,session,cookie,login,def
From: https://www.cnblogs.com/zkz0206/p/16999514.html