Django-cookie-session
为什么会出现Cookie, Session
cookie和session都是为了弥补http协议的无状态特性,对server端来说无法知道两次http请求是否来自同一个用户,利用cookie和session就可以让用户只登录一次,server就知道某个请求是否需用重新登录。
什么是Cookie, Session ?
1.cookie:客户端第一次正常访问服务器,服务器在response headers中返回与用户信息相关的cookie,客户端收到后把cookie保存在本地,下次再发请求时会在request headers中带上这个cookie,服务器收到这个cookie就知道用户状态了。cookie可以设置过期时间,默认值是-1,表示关闭浏览器时cookie就会失效,值为0时表示立马失效,相当于删除cookie(cookie没有删除的方法),服务器和客户端都可以设置cookie,但不可以操作另一个域名下的cookie。
2.session: 客户端第一次正常访问服务器,服务器生成一个sessionid来标识用户并保存用户信息(服务器有一个专门的地方来保存所有用户的sessionId),在response headers中作为cookie的一个值返回,客户端收到后把cookie保存在本地,下次再发请求时会在request headers中带上这个sessionId,服务器通过查找这个sessionId就知道用户状态了,并更新sessionId的最后访问时间。sessionId也会可以设置失效时间,比如如果60分钟内某个session都没有被更新,服务器就会删除这个它。
总言之cookie是保存在客户端,session是存在服务器,session依赖于cookie。
COOKIE
设置cookie
cookie的设置其实就是浏览器在做的,服务端发来数据告诉浏览器,帮我设置一个cookie,浏览器可以拒绝,但是浏览器一般都是默认帮设置的
Django设置cookie要在原来的基础上稍作改变
return HttpResponse()
return render()
return redirect()
变形:把之前返回的对象,多做一步操作,设置一个cookie,其实还是和原来差不多的
zx = HttpResponse()
return zx
zx = render()
return zx
zx = redirect()
return zx
zx.set_cookie('zx',"zx125")
return zx
set_cookie的参数
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存在浏览器都是明文的,可以直接查看到内容
obj.set_signed_cookie('zx','zx125',salt="wl")
cookies=request.get_signed_cookie('zx',salt='wl')
获取和删除
设置cookie
zx.set_cookie()
获取
request.COOKIES.get()
删除
zx.delete_cookie()
SESSION
session设置-获取-删除
request.session.get('zx',zx125)
request.session['zx'] = zx125#只是在内存中产生了一个缓存
request.session.setdefault('zx',123) # 存在则不设置
1.django会产生一个随机的字符串
2.在django的session表中存入数据,数据页被加密,看不到内容,但是取出来的数据是经过解密的
del request.session['zx']
# 会话session的key
request.session.session_key
# 将所有Session失效日期小于当前日期的数据删除
request.session.clear_expired()
# 检查会话session的key在数据库中是否存在
request.session.exists("session_key")
request.session.delete() # 删除当前会话的所有Session数据
request.session.flush() # 删除当前的会话Session并删除Cookie
Session失效
# 设置会话Session和Cookie的超时时间
request.session.set_expiry(value)
* 如果value是个整数,session会在些秒数后失效。
* 如果value是个datatime或timedelta,session就会在这个时间后失效。
* 如果value是0,用户关闭浏览器session就会失效。
* 如果value是None,session会依赖全局session失效策略。
django-session配置
配置setting.py
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存储方式
数据库(默认)
缓存(memchache、redis)
文件
缓存+数据库
加密cookie
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的特点
1.生命周期为一次会话(浏览器关闭失效,因为cookie的生命周期默认为浏览器的缓存)
2.一个浏览器只能登陆一个用户,多个不同的浏览器可以登录多个
3.由于session_id是存在cookie中的所以cookie一定要保存好
session流程图
session实现登录-FBV
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 == "zx" and pwd == "zx125
# 设置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})
CBV实现的三种方式
其实都是一样的
#加在get或者post方法上面
@method_decorator(check_login)
def post(self, request):
print("Home View POST method...")
return redirect("/index/")
#加在dispatch方法上
@method_decorator(check_login)
def dispatch(self, request, *args, **kwargs):
return super(HomeView, self).dispatch(request, *args, **kwargs)
# 直接加在视图类上,但method_decorator必须传 name 关键字参数
from django.utils.decorators import method_decorator
@method_decorator(check_login, name="get")
@method_decorator(check_login, name="post")
class HomeView(View):
def dispatch(self, request, *args, **kwargs):
return super(HomeView, self).dispatch(request, *args, **kwargs)
def get(self, request):
return render(request, "home.html")
def post(self, request):
print("Home View POST method...")
return redirect("/index/")
参考链接
https://www.cnblogs.com/yuanchenqi/articles/7439088.html#3770465