zoukankan      html  css  js  c++  java
  • django cookie and session

    cookie和session

    1、cookie不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此cookie就是在这样一个场景下诞生。

    cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上cookie,这样服务器就能通过cookie的内容来判断这个是“谁”了。

    2、cookie虽然在一定程度上解决了“保持状态”的需求,但是由于cookie本身最大支持4096字节,以及cookie本身保存在客户端,可能被拦截或窃取,因此就需要有一种新的东西,它能支持更多的字节,并且他保存在服务器,有较高的安全性。这就是session。

    问题来了,基于http协议的无状态特征,服务器根本就不知道访问者是“谁”。那么上述的cookie就起到桥接的作用。

    我们可以给每个客户端的cookie分配一个唯一的id,这样用户在访问时,通过cookie,服务器就知道来的人是“谁”。然后我们再根据不同的cookie的id,在服务器上保存一段时间的私密资料,如“账号密码”等等。

    3、总结而言:cookie弥补了http无状态的不足,让服务器知道来的人是“谁”;但是cookie以文本的形式保存在本地,自身安全性较差;所以我们就通过cookie识别不同的用户,对应的在session里保存私密的信息以及超过4096字节的文本。

    4、另外,上述所说的cookie和session其实是共通性的东西,不限于语言和框架

    前几节的介绍中我们已经有能力制作一个登陆页面,在验证了用户名和密码的正确性后跳转到后台的页面。但是测试后也发现,如果绕过登陆页面。直接输入后台的url地址也可以直接访问的。这个显然是不合理的。其实我们缺失的就是cookie和session配合的验证。有了这个验证过程,我们就可以实现和其他网站一样必须登录才能进入后台页面了。

          先说一下这种认证的机制。每当我们使用一款浏览器访问一个登陆页面的时候,一旦我们通过了认证。服务器端就会发送一组随机唯一的字符串(假设是123abc)到浏览器端,这个被存储在浏览端的东西就叫cookie。而服务器端也会自己存储一下用户当前的状态,比如login=true,username=hahaha之类的用户信息。但是这种存储是以字典形式存储的,字典的唯一key就是刚才发给用户的唯一的cookie值。那么如果在服务器端查看session信息的话,理论上就会看到如下样子的字典

    {'123abc':{'login':true,'username:hahaha'}}

    因为每个cookie都是唯一的,所以我们在电脑上换个浏览器再登陆同一个网站也需要再次验证。那么为什么说我们只是理论上看到这样子的字典呢?因为处于安全性的考虑,其实对于上面那个大字典不光key值123abc是被加密的,value值{'login':true,'username:hahaha'}在服务器端也是一样被加密的。所以我们服务器上就算打开session信息看到的也是类似与以下样子的东西

    {'123abc':dasdasdasd1231231da1231231}

    借用一张别的大神画的图,可以更直观的看出来cookie和session的关系

    cookie示例:

    urls.py

    from django.conf.urls import url
    from django.contrib import admin
    
    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^login/', views.login),
        url(r'^index/', views.index),
    
    ]

    views.py

    from django.shortcuts import render,redirect
    
    # Create your views here.
    
    
    def login(request):
        print("COOKIES",request.COOKIES)
        if request.method=="POST":
            name=request.POST.get("user")
            pwd=request.POST.get("pwd")
            if name=="nulige" and pwd=="oldboy123":
    
                ret=redirect("/index/")
                ret.set_cookie("blili","acfine")
                return ret
    
        return render(request,"login.html")
    
    def index(request):
    
        if request.COOKIES.get("blili",None)=="acfine":
            name = "yuan"
            # name = request.COOKIES.get("username",None)
            return render(request, "index.html", locals())
    
        else:
            return redirect("/login/")

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
    
        <title>Title</title>
    
    </head>
    <body>
    
    <h1>{{ name }}</h1>
    
    </body>
    </html>

    login.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
    
        <title>Title</title>
    
    </head>
    <body>
    
    <form action="/login/" method="post">
        <p>姓名<input type="text" name="user"></p>
        <p>密码<input type="password" name="pwd"></p>
        <p><input type="submit"></p>
    </form>
    
    
    </body>
    </html>

    运行效果:

    验证能过的效果:

    cookie and session设置过期时间示例:

    设置过期时间参数语法:

    views.py

    from django.shortcuts import render,redirect
    
    # Create your views here.
    
    import datetime
    
    def login(request):
        print("COOKIES",request.COOKIES)
        print("SESSION",request.session)
        if request.method=="POST":
            name=request.POST.get("user")
            pwd=request.POST.get("pwd")
            if name=="nulige" and pwd=="oldboy123":
    
                ret = redirect("/index/")
                #设置过期时间,max_age 和 expires 时间要设置的一样。
                # ret.set_cookie("username", {"11": "22"})
                ret.set_cookie("username", {"11":"22"},max_age=10,expires=datetime.datetime.utcnow()+datetime.timedelta(days=3))
                return ret
    
                #COOKLE SESSION
                # request.session["is_login"]=True
                # request.session["user"]=name
                # return redirect("/index/")
    
        return render(request,"login.html")
    
    
    def index(request):
    
        if request.COOKIES.get("username",None):
            name = request.COOKIES.get("username",None)
            return render(request, "index.html", locals())
    
        # if request.session.get("is_login",None):
        #     name=request.session.get("user",None)
        #     return render(request,"index.html",locals())
    
        else:
            return redirect("/login/")

     session的内容:

    1、login页面正确登录的话,后台页面可以获取到浏览器携带的cookie的。

    2、第一行的sessionid其实就是cookie值

    3、session的内容是加密的,从客户端获取不到session的内容

    4、服务端可以通过预设的key值取出session的内容并打印到前段

    5、django的session默认是存储在数据库里的,我们再到数据库查看一下真正session内容

    下面我们再来最后的总结一下cookie和session的知识

    一、操作Cookie

      获取cookie:request.COOKIES[key]

      设置cookie:response.set_cookie(key,value)

    由于cookie保存在客户端的电脑上,所以,jquery也可以操作cookie。

    <script src='http://830909.blog.51cto.com/static/js/jquery.cookie.js'></script>
    $.cookie("list_pager_num", 30,{ path: '/' });

    二、操作Session(session默认在服务器端保存15天)

      获取session:request.session[key]

      设置session:reqeust.session[key] = value

      删除session:del request.session[key]    

    (这个删除其实就是把数据库的session_data更新为一个其他的值了,并没有立即删除)

    request.session.set_expiry(value)
    * 如果value是个整数,session会在些秒数后失效。
    * 如果value是个datatime或timedelta,session就会在这个时间后失效。
    * 如果value是0,用户关闭浏览器session就会失效。
    * 如果value是None,session会依赖全局session失效策略。

    session示例:

     settings.py

    """
    Django settings for Django_cookie_session project.
    
    Generated by 'django-admin startproject' using Django 1.10.5.
    
    For more information on this file, see
    https://docs.djangoproject.com/en/1.10/topics/settings/
    
    For the full list of settings and their values, see
    https://docs.djangoproject.com/en/1.10/ref/settings/
    """
    
    import os
    
    # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    
    
    # Quick-start development settings - unsuitable for production
    # See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/
    
    # SECURITY WARNING: keep the secret key used in production secret!
    SECRET_KEY = 'c!liyw7j1xrxljktnfl#q736^b@=uhf5=$6qfw=5i5_0qvy2c*'
    
    # SECURITY WARNING: don't run with debug turned on in production!
    DEBUG = True
    
    ALLOWED_HOSTS = []
    
    
    # Application definition
    
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app01',
    ]
    
    # MIDDLEWARE =
    MIDDLEWARE_CLASSES = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
       # 'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ]
    
    ROOT_URLCONF = 'Django_cookie_session.urls'
    
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates')]
            ,
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]
    
    WSGI_APPLICATION = 'Django_cookie_session.wsgi.application'
    
    
    DATABASES = {
    
        'default': {
    
            'ENGINE': 'django.db.backends.mysql',
    
            'NAME': 'django_admin',
    
            'USER': 'root',
    
            'PASSWORD': 'oldboy123',
    
            'HOST': '',
    
            'PORT': '3306',
    
        }
    
    }
    
    
    # Password validation
    # https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
    
    AUTH_PASSWORD_VALIDATORS = [
        {
            'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
        },
    ]
    
    
    # Internationalization
    # https://docs.djangoproject.com/en/1.10/topics/i18n/
    
    LANGUAGE_CODE = 'en-us'
    
    TIME_ZONE = 'UTC'
    
    USE_I18N = True
    
    USE_L10N = True
    
    USE_TZ = True
    
    
    # Static files (CSS, JavaScript, Images)
    # https://docs.djangoproject.com/en/1.10/howto/static-files/
    
    STATIC_URL = '/static/'

    views.py

    from django.shortcuts import render,redirect
    
    # Create your views here.
    
    def login(request):
        print("COOKIES",request.COOKIES)
        print("SESSION",request.session)
        if request.method=="POST":
            name=request.POST.get("user")
            pwd=request.POST.get("pwd")
            if name=="nulige" and pwd=="oldboy123":
    
                #COOKLE SESSION
                request.session["is_login"]=True
                request.session["user"]=name
    
                return redirect("/index/")
        return render(request,"login.html")
    
    
    def index(request):
    
        if request.session.get("is_login",None):
            name=request.session.get("user",None)
            return render(request,"index.html",locals())
        else:
            return redirect("/login/")

    urls.py

    from django.conf.urls import url
    from django.contrib import admin
    
    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^login/', views.login),
        url(r'^index/', views.index),
    
    ]

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    
    </head>
    <body>
    
    <form action="/login/" method="post">
        <p>姓名<input type="text" name="user"></p>
        <p>密码<input type="password" name="pwd"></p>
        <p><input type="submit"></p>
    </form>
    
    </body>
    </html>

    运行效果:

    再换一个浏览器,还是需要输入用户名和密码

  • 相关阅读:
    sql server 2008 不允许保存更改,您所做的更改要求删除并重新创建以下表 的解决办法
    给 textbox TextMode="password" 赋值后显示出来
    mysql limit分页优化方法分享
    jquery iframe取得元素与自适应高度
    js动态改变iframe的高度
    完全解读 margin 标签
    Page.ClientScript、ClientScript、ScriptManager、ClientScriptManager等的详细解说
    Asp.net C# 使用Newtonsoft.Json 实现DataTable转Json格式数据
    Newtonsoft.Json(Json.net)的基本用法
    利用navicat创建存储过程、触发器和使用游标的简单实例
  • 原文地址:https://www.cnblogs.com/nulige/p/6497311.html
Copyright © 2011-2022 走看看