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

  • 相关阅读:
    const变量指针赋值给非const类型的指针运行结果
    嵌套结构可以访问外部结构的私有成员吗?
    几种cms的介绍
    中国互联网网站尴尬排行榜[转]
    如何跨域来同步不同网站之间的Cookie
    CMS整站程序整理
    vs 设置断点
    ASP.NET 4中的SEO改进
    VSS演示
    发生一个未处理的异常 脚本调试 错误号2912
  • 原文地址:https://www.cnblogs.com/zx125/p/11768637.html
Copyright © 2011-2022 走看看