Cookie 与 Session 的 写 /删/取/其他相关属性操作 ,Django中的session配置,CBV登陆认证装饰器,FBV登陆认证装饰器
Cookie
存在客户端浏览器上的键值对
cookie原理
cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上Cookie,这样服务器就能通过Cookie的内容来判断这个是“谁”了。
cookie覆盖
如果服务器端发送重复的Cookie那么会覆盖原有的Cookie,
例如:
客户端的第一个请求服务器端发送的Cookie是:Set-Cookie: a=A;
第二请求服务器端发送的是:Set-Cookie: a=AA,
那么客户端只留下一个Cookie,即:a=AA。
写cookie
(1)写cookie [ 基于 Httpresponse 上写 ] obj = Httpresponse('ok') obj.set_cookie( key,value ) obj.set_cookie( 'name','lxx' ) # 写cookie
获取cookie
# 取cookie
request.COOKIES (字典的形式)
删除cookie
# 删cookie obj = Httpresponse('ok') obj.delete_cookie( 'name' ) # 删除cookie
cookie其他属性
# 加盐的cookie salt = '123' obj = Httpresponse('ok') obj.set_signed_cookie('name','lxx',salt='123')
# 超时时间( max_age/expires ) # max_age : 传一个秒的时间 # expires : 传一个 datatime 对象 obj.set_cookie( 'name','lxx',max_age=5 ) # path 指定路径下 path='/index/' obj.set_cookie('name','lxx',path='/index/') domain='map.baidu.com' # 设置域名下有效
obj.set_cookie('name','lxx',domain='map.baidu.com') secure=False, # (默认是false,设置成True浏览器将通过HTTPS来回传cookie)
httponly=True # 只能https协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)
Cookie其他参数
- key, 键
- value='', 值
- max_age=None, 超时时间 cookie需要延续的时间(以秒为单位)如果参数是\ None`` ,这个cookie会延续到浏览器关闭为止
- expires=None, 超时时间(IE requires expires, so set it if hasn't been already.)
- path='/', Cookie生效的路径,/ 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问,浏览器只会把cookie回传给带有该路径的页面,这样可以避免将cookie传给站点中的其他的应用。
- domain=None, Cookie生效的域名 你可用这个参数来构造一个跨站cookie。如, domain=".example.com"所构造的cookie对下面这些站点都是可读的:www.example.com 、 www2.example.com 和an.other.sub.domain.example.com 。如果该参数设置为 None ,cookie只能由设置它的站点读取
- secure=False, 浏览器将通过HTTPS来回传cookie
- httponly=False 只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)
练习 :
写一个 cookie 登陆认证
session
存在服务器上的键值对 ( 解决了 cookie 不安全问题)
写session
def set_session(request): request.session['name'] = 'wxx' request.session['sex'] = 'age' return HttpResponse('ok')
取session
name = request.session['name']
删session
(3)删 session [ delete/flush ]
delete : 删 数据库
flush: 删 cooKie 与 数据库
eg: request.session.flush()
Django中使用session所作的事情 ( 操作流程 )
(1)生成随机字符串 (2)去数据库存储成
# 数据库形式 随机字符串 值(字典形式) 超时时间 session_key session_data expire_data (3)写入Cookie
set_cookie( 'sessionid','随机码') ) 浏览器上 sessionid = firqu3ftct2moj76c4wbl8pq4gi4dq99
session的其他属性
# 获取、设置、删除Session中数据 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() # 会话session的key request.session.session_key # 将所有Session失效日期小于当前日期的数据删除 request.session.clear_expired() # 检查会话session的key在数据库中是否存在 request.session.exists("session_key") # 删除当前会话的所有Session数据(只删数据库) request.session.delete() # 删除当前的会话数据并删除会话的Cookie(数据库和cookie都删)。 request.session.flush() 这用于确保前面的会话数据不可以再次被用户的浏览器访问 例如,django.contrib.auth.logout() 函数中就会调用它。 # 设置会话Session和Cookie的超时时间 request.session.set_expiry(value) * 如果value是个整数,session会在些秒数后失效。 * 如果value是个datatime或timedelta,session就会在这个时间后失效。 * 如果value是0,用户关闭浏览器session就会失效。 * 如果value是None,session会依赖全局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,默认修改之后才保存(默认)
FBV登陆认证装饰器
作业:
1 基于session写一个登陆认证装饰器,登陆之后才能查看订单页面,购物页面
# 登陆函数 def login(request): if request.method == 'GET': return render(request, 'login.html') if request.method == 'POST': name = request.POST.get('name') pwd = request.POST.get('pwd') print(name) print(pwd) if name == 'lxx' and pwd == '123': # # 登陆通过 写 session # print(1) request.session['name'] = name request.session['pwd'] = pwd print( request.session.session_key ) # print(2) return redirect('/order/') else: return redirect('/login/') # # session装饰器 def session_auth(func): def inter(request,*args,**kwargs): if request.session.session_key: return func(request,*args,**kwargs) else: return redirect('/userlist/') return inter # 订单函数 @session_auth def order(request): return HttpResponse('我是订单页面') # 购物函数 @session_auth def shopping(request): return HttpResponse('我是购物页面')
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>登陆页面</title> </head> <body> <form action="/login/" method="post"> <p>用户名:<input type="text" name="name"></p> <p>密码:<input type="text" name="pwd"></p> <input type="submit" name="提交"> </form> </body> </html>
CBV登陆认证装饰器
2 应用到cbv上
#登陆认证装饰器 def login_auth(func): def inner(request,*args,**kwargs) ret = request.session.get('id') if ret: return func(request,*args,**kwargs) else: return redirect('/login/') return inner # 给订单order添加装饰器 from django.utils.decorators import method_decorator # @method decorator(login_auth ,name='get',) # 给类加装饰器,需指定名字 # @method decorator(login_auth ,name='post',) # 给类加装饰器,需指定名字 class Order(views.View): # @method_decorator(login_auth) #给所有的都加了装饰器 def dispatch(self, request, *args, **kwargs): obj=super().dispatch(request, *args, **kwargs) return obj @method decorator(login_auth) #只给查看订单的 get请求 加了登陆认证装饰器 def get( self,request,*args,**kwargs ): return HttpResponse('我是查看订单页面') @method decorator(login_auth) #只给查看订单的 post请求 加了登陆认证装饰器 def post( self,request,*args,**kwargs ) return HttpResponse('我是查看订单页面')