cookie与session
目录
cookie 与 session:
cookie 与 session 原理:
1.保存客户端的用户状态
2.产生原因 : HTTP协议是无状态的(不会保存用户的状态)
cookie:
cookie介绍 ;
指的是一段小信息,它是服务器发送出来存储在浏览器上的一组组键值对,下次访问服务器时浏览器会自动携带这些键值对,以便服务器提取有用信息
cookie查看 : 在浏览器上开发者模式,Network--->all---> Cookie
优点 : 服务端不用存储用户数据,减轻了服务器的压力
缺点 : 信息保存在客户端,信息不安全性增加(web领域内没有一定的安全)
django内操作Cookie
django内操作Cookie:
#获取cookie :
request.COOKIES['key'] 获取普通版cookie
加盐版cookie (加密)
request.get_signed_cookie(key,default=RAISE_ERROR,salt='',max_age=None)
参数 : default :默认值 salt: 加密盐('') max_age : 后台控制过期时间(单位:秒)
#设置Cookie :
1.方式一 : 在view.py中给返回给客户端的响应数据中设置Cookie
rep = HttpResponse(...) #获取 HttpResponse对象
rep = render(request,...)
rep.set_cookie(key,value....) #键值对形式
2.方式二 :在view.py中给返回给客户端的响应数据中设置Cookie
rep = HttpResponse(....)
rep = render(request,...)
rep.set_signed_cookie(key,value,salt='添加加密盐',....)
#删除cookie :
def logout(request):
rep = redirect('/login/')
rep.delete_cookie('user') # 清除客户端的cookie数据
return rep
参数:
key : 键 value : 值
path = '/': Cookie生效的路径,/ 表示根路径,根路径的cookie可以被任何url的页面访问
demain = None , Cookie生效的域名
secure = False, http传输
httponly = False 只能http协议传输,无法被JavaScript获取
设置超时时间:
#设置超时时间:
max_age 与 expires的区别:
max_age = 秒 (不支持IE 浏览器)
expires = 秒 (支持IE 浏览器)
max_age : 超时时间
request.session.set_expiry(value)
value : 整数 , datetime , none (django内的时间为准), 0 (关闭页面消失)
request.session.set_expiry(value)
* 如果value是个整数,session会在些秒数后失效。
* 如果value是个datatime或timedelta,session就会在这个时间后失效。
* 如果value是0,用户关闭浏览器session就会失效。
* 如果value是None,session会依赖全局session失效策略。
注意:在django内默认的expire_data : 超时时间(2周)
cookie版登录:
from functools import wraps
def check_login(func):
@wraps(func)
def inner(request,*args,**kwargs):
next_url = request.get_full_path()
if request.get_signed_cookie('login',salt='sss',default=None) == 'yes':
return func(request,*args,**kwargs)
else:
return redirect("login/?next={}".format(next_url))
return inner
def login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'jason' and password == "123":
next_url = request.GET.get('next')
if next_url and next_url!= '/logout/':
response = redirect(next_url)
else:
response = redirect('class_list')
response.set_signed_cookie('login','yes',salt='sss')
return response
return render(request,'login.html')
request.path_info #只获取 url
request.get_full_path() # 获取url + get 请求参数
session:
session介绍:
-cookie 的缺陷 : Cookie本身最大支持4096字节,以及Cookie本身保存在客户端,可能被拦截或窃取
-session : 保存私密的信息以及超过4096字节的文本。保存在服务端
--》工作机制需要依赖于cookie,在限定时间内 同一种上浏览器的session值相同,且在django内自动创建(django_session表 --需手动同步数据库),一种浏览器就对应一条数据
创建session所发生的事件:
1.djang内部自动帮你调用算法生成一个随机的字符串
2.在django_session添加数据(数据也是加密处理)
随机字符串 加密之后的数据 失效时间
ashdjsad(key) jsadsada(value) set_expiry(value) 默认2周
3.将产生的随机字符串返回给客户端浏览器 让浏览器保存
sessionid:随机字符串
session相关方法:
#1. 获取 , 设置 , 删除 session内的数据
request.session['k1']= v1
.... 注意 : 先执行同步数据库命令生成django_session表;
request.session.get('k1')
#删除:
request.session.delete() 删除双方的所有session(只删除单个浏览器上的对应的数据)
request.session.flush() 删除客服端 (推荐)
#2.所有 键、值、键值对
request.session.keys()
request.session.values()
request.session.items()
request.session.iterkeys()
request.session.itervalues()
request.session.iteritems()
# 会话session的key
request.session.session_key
# 将所有Session失效日期小于当前日期的数据删除
request.session.clear_expired()
# 检查会话session的key在数据库中是否存在
request.session.exists("session_key")
# 删除当前会话的所有Session数据
request.session.delete()
# 删除当前的会话数据并删除会话的Cookie。
request.session.flush()
这用于确保前面的会话数据不可以再次被用户的浏览器访问
例如,django.contrib.auth.logout() 函数中就会调用它
注意: django session 创建数据的时候,针对的是浏览器(创建数据的数据)
-->服务端数据只识别浏览器,不识别客服端的操作者!!!
django内session设置:
1. 数据库Session
SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认)
2. 缓存Session
SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎
SESSION_CACHE_ALIAS = 'default' # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
3. 文件Session
SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎
SESSION_FILE_PATH = None # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()
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保存在浏览器上时的key,即:sessionid=随机字符串(默认)
SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径(默认)
SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默认)
SESSION_COOKIE_SECURE = False # 是否Https传输cookie(默认)
SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输(默认)
SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(默认)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期(默认)
SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存(默认)
session版登录验证:
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))
def login(request):
if request.method == 'POST':
user = request.POST.get('user')
pwd = request.POST.get('pwd')
if user == 'jason' and pwd == '123':
request.session['user'] = user
next_url = request.GET.get('next')
if next_url:
return redirect(next_url)
else:
return redirect(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',locals())
token
-能够作为数据库 :
1. 数据库软件 (关系型 , 非关系型)
2. 文件 , 内存
--》多用户下处理认证的最佳方式。
产生原因 :
1.Seesion:每次认证用户发起请求时,服务器需要去创建一个记录来存储信息。当越来越多的用户发请求时,内存的开销也会不断增加。
2.可扩展性:在服务端的内存中使用Seesion存储登录信息,伴随而来的是可扩展性问题。
3.CORS(跨域资源共享):当我们需要让数据跨多台移动设备上使用时,跨域资源的共享会是一个让人头疼的问题。在使用Ajax抓取另一个域的资源,就可以会出现禁止请求的情况。
4.CSRF(跨站请求伪造):用户在访问银行网站时,他们很容易受到跨站请求伪造的攻击,并且能够被利用其访问其他的网站。
Token的优点 :
1.无状态 ,可扩展 :客户端存储的Tokens是无状态的,并且能够被扩展
2.安全性 :请求中发送token而不再是发送cookie能够防止CSRF(跨站请求伪造)
3.可扩展性 :能够创建与其它程序共享权限的程序
4.多平台跨域 :用户有一个通过了验证的token,数据和资源就能够在任何域上被请求到。
流程:
1.用户登录校验,校验成功后就返回Token给客户端。
2.客户端收到数据后保存在客户端
3.客户端每次访问API是携带Token到服务器端。
4.服务器端采用filter过滤器校验。校验成功则返回请求数据,校验失败则返回错误码