Cookie & Session
https://www.cnblogs.com/liwenzhou/p/8343243.html
Cookie
Cookie是什么
保存在浏览器端的键值对
为什么要有Cookie
因为HTTP请求是无状态的
Cookie的原理
服务端可以在返回响应的时候 做手脚
在浏览器上写入键值对,就是Cookie,浏览器发送请求的时候会自动携带该网站保存在浏览器中的键值对
Cookie的使用场景
- 保存登录信息
- 保存用户的搜索关键词
Django中操作Cookie
获取Cookie
1 2 3 4 5 6 7
| request.COOKIES['key'] request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
参数: default: 默认值 salt: 加密盐 max_age: 后台控制过期时间
|
设置Cookie
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| rep = HttpResponse(...) rep = render(request, ...)
rep.set_cookie(key,value,...) rep.set_signed_cookie(key,value,salt='加密盐', max_age=None, ...)
参数: key, 键 value='', 值 max_age=None, 超时时间 expires=None, 超时时间(IE requires expires, so set it if hasn't been already.) path='/', Cookie生效的路径,/ 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问 domain=None, Cookie生效的域名 secure=False, https传输 httponly=False 只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)
|
删除Cookie
1 2 3 4
| def logout(request): rep = redirect("/login/") rep.delete_cookie("user") return rep
|
完整views.py示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| from __future__ import unicode_literals from django.shortcuts import render,redirect from django.http import HttpResponse,HttpResponseRedirect from django.shortcuts import render
def check_login(func): def a(request,*args,**kwargs): Cookies = request.COOKIES.get("is_login", None) if 'yes' != Cookies: return redirect('/test01/login') else: return func(request,*args,**kwargs) return a @check_login def index(request): return HttpResponse('index界面')
@check_login def home(request): return HttpResponse('home')
def login(request): return render(request,'test01/login.html')
@check_login def logout(request): rep = redirect('/test01/login') rep.delete_cookie('is_login') return rep
def check_username(request): if request.method == "POST": username = request.POST.get('username',None) password = request.POST.get('password',None) if username == 'z' and password == 'z': rep = render(request,'test01/home.html',{'username':username}) rep.set_signed_cookie('is_login', 'yes', expires=60 * 60 * 24 * 7) else: rep = redirect('/test01/login') else: rep = redirect('/test01/login')
return rep
|
Session
Cookie虽然在一定程度上解决了“保持状态”的需求,但是由于Cookie本身最大支持4096字节,以及Cookie本身保存在客户端,可能被拦截或窃取,因此就需要有一种新的东西,它能支持更多的字节,并且他保存在服务器,有较高的安全性。这就是Session。
问题来了,基于HTTP协议的无状态特征,服务器根本就不知道访问者是“谁”。那么上述的Cookie就起到桥接的作用。
我们可以给每个客户端的Cookie分配一个唯一的id,这样用户在访问时,通过Cookie,服务器就知道来的人是“谁”。然后我们再根据不同的Cookie的id,在服务器上保存一段时间的私密资料,如“账号密码”等等。
总结而言:Cookie弥补了HTTP无状态的不足,让服务器知道来的人是“谁”;但是Cookie以文本的形式保存在本地,自身安全性较差;所以我们就通过Cookie识别不同的用户,对应的在Session里保存私密的信息以及超过4096字节的文本。
另外,上述所说的Cookie和Session其实是共通性的东西,不限于语言和框架。
Django中操作Session
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| request.session['k1'] request.session.get('k1',None) request.session['k1'] = 123 request.session.setdefault('k1',123) del request.session['k1']
request.session.keys() request.session.values() request.session.items() request.session.iterkeys() request.session.itervalues() request.session.iteritems()
request.session.session_key
request.session.clear_expired()
request.session.exists("session_key")
request.session.delete()
request.session.flush() 这用于确保前面的会话数据不可以再次被用户的浏览器访问 例如,django.contrib.auth.logout() 函数中就会调用它。
request.session.set_expiry(value) * 如果value是个整数,session会在些秒数后失效。 * 如果value是个datatime或timedelta,session就会在这个时间后失效。 * 如果value是0,用户关闭浏览器session就会失效。 * 如果value是None,session会依赖全局session失效策略。
|
Seesion版验证登录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| from functools import wraps
def check_login(func): @wraps(func) def inner(request, *args, **kwargs): next_url = request.get_full_path() if request.session.get("user"): return func(request, *args, **kwargs) else: return redirect("/login/?next={}".format(next_url)) return inner
def login(request): if request.method == "POST": user = request.POST.get("user") pwd = request.POST.get("pwd")
if user == "alex" and pwd == "alex1234": request.session["user"] = user next_url = request.GET.get("next") if next_url: return redirect(next_url) else: return redirect("/index/") return render(request, "login.html")
@check_login def logout(request): request.session.delete() return redirect("/login/")
@check_login def index(request): current_user = request.session.get("user", None) return render(request, "index.html", {"user": current_user})
|
Django中的Session配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| 1. 数据库Session SESSION_ENGINE = 'django.contrib.sessions.backends.db'
2. 缓存Session SESSION_ENGINE = 'django.contrib.sessions.backends.cache' SESSION_CACHE_ALIAS = 'default'
3. 文件Session SESSION_ENGINE = 'django.contrib.sessions.backends.file' SESSION_FILE_PATH = None
4. 缓存+数据库 SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'
5. 加密Cookie Session SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'
其他公用设置项: SESSION_COOKIE_NAME = "sessionid" SESSION_COOKIE_PATH = "/" SESSION_COOKIE_DOMAIN = None SESSION_COOKIE_SECURE = False SESSION_COOKIE_HTTPONLY = True SESSION_COOKIE_AGE = 1209600 SESSION_EXPIRE_AT_BROWSER_CLOSE = False SESSION_SAVE_EVERY_REQUEST = False
|