zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    1442. Count Triplets That Can Form Two Arrays of Equal XOR
    1441. Build an Array With Stack Operations
    312. Burst Balloons
    367. Valid Perfect Square
    307. Range Sum Query
    1232. Check If It Is a Straight Line
    993. Cousins in Binary Tree
    1436. Destination City
    476. Number Complement
    383. Ransom Note
  • 原文地址:https://www.cnblogs.com/zx125/p/11768637.html
Copyright © 2011-2022 走看看