目录
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过滤器校验。校验成功则返回请求数据,校验失败则返回错误码