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,浏览器可以拒绝,但是浏览器一般都是默认帮设置的

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

原文地址:https://www.cnblogs.com/zx125/p/11768637.html