cookie与session简介
-简介
什么是cookie
cookie具体指的是一段小信息,它是服务器发送出来存储在浏览器上的一组组键值对,下次访问服务器时浏览器会自动携带这些键值对,以便服务器提取有用信息
cookie的原理
cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上cookie,这样服务器就能通过cookie的内容来判断这个是“谁”了
查看cookie
session的由来
cookie虽然在一定程度上解决了“保持状态”的需求,但是由于cookie本身最大支持4096字节,以及cookie本身保存在客户端,可能被拦截或窃取,因此就需要有一种新的东西,它能支持更多的字节,并且它保存在服务器,有较高的安全性。这就是session
cookie和session其实是共通性的东西,session是基于cookie工作的
-Django操作cookie
cookie即是服务端告诉客户端浏览器需要保存的内容,但客户端也可选择拒绝保存,如edge浏览器中设置关闭“允许站点保存和读取 Cookie 数据(推荐)”,则会导致一些网站访问不进去或每点击一个网页都需登录。
PS:
Django要想操作cookie,之前Django三板斧(render,HttpResponse,redirect)都是直接return xxx(),但若想操作cookie则需先: obj = xxx() 操作cookie语句 # 必须先用obj对象接收,在中间操作 return obj
方法:
设置cookie: obj.set_cookie(key, value) 获取cookie: request.COOKIE.get(key) 设置超时时间(一段时间未登录自动注销): obj.set_cookie(key, value, max_age = num) # 单位为秒 PS: IE浏览器为expires参数 注销功能: obj.delete_cookie(key)
cookie版登录
from django.shortcuts import render,redirect,HttpResponse # Create your views here. # 装饰器 def jump_auto(func): """ 要想实现未登录时由其跳转回登录界面,登录成功后又自动跳回,每个路由函数下都要写target_url等代码过于繁琐 所以利用装饰器来简化 """ def inner(request, *args, **kwargs): # 得到输入路由 target_url = request.path_info # 判断进入 if request.COOKIES.get('credential') == 'weer888': return func(request, *args, **kwargs) else: return redirect('/login/?url=%s' % target_url) return inner def login(request): # 登录成功后跳转 if request.method == 'POST': # 获取上次地址栏中输入的路由 target_url = request.GET.get('url') """ 当用户未登录时,应该是从哪个路由跳过来的login界面 登录后应该自动跳转回该页面,所以用url来存 """ username = request.POST.get('username') password = request.POST.get('password') # 登录校验(死) if username == 'weer' and password == '666': if target_url: # 生成cookie对象 obj = redirect(target_url) else: obj_home = redirect('/home/') obj_home.set_cookie('credential', 'weer888') return obj_home # cookie中不能含有中文 obj.set_cookie('credential', 'weer888') # 登录成功后跳转页面 return obj return render(request, 'login.html') @jump_auto def home(request): # 不用装饰器时 # # 得到输入路由 # target_url = request.path_info # if request.COOKIES.get('credential') == 'weer888': # return render(request, 'home.html') # # 在地址栏用url存放 # return redirect('/login/?url=%s' % target_url) # 利用装饰器后直接 return render(request, 'home.html') @jump_auto def index(request): # 不用装饰器时 # if request.COOKIES.get('credential') == 'weer888': # return HttpResponse('这是index页面,只有登录者才能进来哦~') # return redirect('/login/') # 利用装饰器后直接 return HttpResponse('这是index页面,只有登录者才能进来哦~') @jump_auto def func(request): # 不用装饰器时 # if request.COOKIES.get('credential') == 'weer888': # return HttpResponse('这是func页面,只有登录者才能进来哦~') # return redirect('/login/') # 利用装饰器后直接 return HttpResponse('这是func页面,只有登录者才能进来哦~') @jump_auto def logout(request): obj_out = redirect('/login/') obj_out.delete_cookie('credential') return obj_out
from django.contrib import admin from django.urls import path from app01 import views urlpatterns = [ path('admin/', admin.site.urls), # 首页 path('home/', views.home), # 登录 path('login/', views.login), # index页面 path('index/', views.index), # func页面 path('func/', views.func), # 注销功能 path('logout/', views.logout), ]
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>首页</title> </head> <body> <p>Welcome to HomePage!只有登录用户才能进哟~</p> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登录</title> </head> <body> <form action="" method="post"> <p>username:<input type="text" name="username"></p> <p>password:<input type="text" name="password"></p> <input type="submit"> </form> </body> </html>
-Django操作session
session是保存在服务端的,给客户端返回的是一个随机字符串
客户端浏览器保存格式: sessionid : 随机字符串
那session产生的随机字符串保存在服务端的哪呢?有多种保存方式:
1、数据库
保存在数据库时,是保存在django_session表中的,包含三个字段:
session_key session_data expiry_date(超时时间,Django默认是14天后)
执行数据库迁移命令,Django自动创建的表中就有一张django_session表
2、文件
3、redis
4、memcache
…
设置session request.session['key'] = value 获取session: request.session.get('key') 设置过期/超时时间: request.session.set_expiry() 括号内有四种参数可选 1.整数 整数秒 2.日期对象 指定日期失效 3.0 浏览器窗口一关闭立刻失效 4.不写 默认14天 清除session: request.session.delete() # 只清除服务端保存的,客户端浏览器的 不删 request.session.flush() # 浏览器和服务端的都删
# 获取、设置、删除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。 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失效策略。
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": # 设置session request.session["user"] = user # 获取跳到登陆页面之前的URL next_url = request.GET.get("next") # 如果有,就跳转回登陆之前的URL if next_url: return redirect(next_url) # 否则默认跳转到index页面 else: return redirect("/index/") return render(request, "login.html") @check_login def logout(request): # 删除所有当前请求相关的session 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}) Session版登录验证
Django中的Session配置
Django中默认支持Session,其内部提供了5种类型的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,默认修改之后才保存(默认) Django中Session相关设置