zoukankan      html  css  js  c++  java
  • cookie和session

    一、cookie和session的介绍

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

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

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

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

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

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

    另外,上述所说的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的简单使用

    1、获取Cookie

    request.COOKIES.get("islogin",None)  #如果有就获取,没有就默认为none

    2、设置Cookie

      obj = redirect("/index/")
      obj.set_cookie("islogin",True)  #设置cookie值,注意这里的参数,一个是键,一个是值
      obj.set_cookie("haiyan","344",20)  #20代表过期时间
      obj.set_cookie("username", username)

    3、删除Cookie

    obj.delete_cookie("cookie_key",path="/",domain=name)

     登录认证示例:

    需要知道几点

    一共有三次请求
      注意:form表单的action走的路径还是/login/
         第一次请求:url:http://127.0.0.1:8080/login get请求
           第一次请求:url:http://127.0.0.1:8080/login post请求 user pasw
           第一次请求:url:http://127.0.0.1:8080/index post请求 携带着cookie的了
           所以在index页面中就会取到cookie,因为这是的index里面已经有cookie了

    urls.py

    1 from app01 import views
    2 urlpatterns = [
    3     url(r'^admin/', admin.site.urls),
    4     url(r'^login/', views.login),
    5     url(r'^index/', views.index),
    6 ]
    View Code

    views.py

     1 from django.shortcuts import render,redirect,HttpResponse
     2 from app01 import models
     3 # Create your views here.
     4 def login(request):
     5     if request.method=="POST":
     6         print("所有请求数据",request.POST)
     7         username = request.POST.get("username")
     8         password = request.POST.get("password")
     9         # 查看数据库中的用户名和密码,对比用户输入的是否是数据库中的值
    10         ret = models.UserInfo.objects.filter(username=username,password=password)
    11         if ret:  #如果用户名和密码都正确,则登录成功
    12             print(request.COOKIES)  #{'csrftoken': '1EaTcdQlxdwtR0eXu4uDqEHElEpOlDRJoSAd7TfA7cBDxAyxADVPbIKaZk6J0DVB'}
    13             # 由于http协议是无状态的,你这次登录完就不知道是谁登录了,当别人知道你的主页url,就都可以登录了。那样就没有隐私了
    14             # 这就得用到cookie了
    15             obj = redirect("/index/")
    16             obj.set_cookie("islogin",True)  #设置cookie值,注意这里的参数,一个是键,一个是值
    17             obj.set_cookie("haiyan","344",20)  #20代表过期时间
    18             obj.set_cookie("username", username)
    19             return obj
    20         else:
    21             return render(request,"login.html")
    22     else:
    23         return render(request,"login.html")
    24 def index(request):
    25     is_login = request.COOKIES.get("islogin",None)  #得到cookie,有就得到,没有就得到none
    26     if is_login:
    27         username = request.COOKIES.get("username")
    28         print(username)
    29         return render(request,"index.html",{"username":username})
    30     else:  #如果没有拿到值,就一直在登录页面就进不去
    31         return redirect("/login/")
    View Code

    models.py

    1 class UserInfo(models.Model):
    2     username =models.CharField(max_length=32)
    3     password =models.CharField(max_length=32)
    View Code

    login.html

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     6     <meta name="viewport" content="width=device-width">
     7     <title>用户登录</title>
     8     <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
     9     <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
    10     <style>
    11         .c1{
    12             margin-top: 100px;
    13         }
    14         .btn{
    15              130px;
    16         }
    17         .c2{
    18             margin-left: 40px;
    19         }
    20     </style>
    21 </head>
    22 <body>
    23 <div class="container">
    24     <div class="row">
    25         <div class="c1 col-md-5 col-md-offset-3">
    26             <form class="form-horizontal" action="/login/" method="post" novalidate>
    27                 {% csrf_token %}
    28                 <div class="form-group">
    29                     <label for="username" class="col-sm-2 control-label">用户名</label>
    30                     <div class="col-sm-10">
    31                         <input type="email" class="form-control" id="username" placeholder="Email" name="username">
    32                     </div>
    33                 </div>
    34                 <div class="form-group">
    35                     <label for="password" class="col-sm-2 control-label">密码</label>
    36                     <div class="col-sm-10">
    37                         <input type="password" class="form-control" name="password" id="password"
    38                                placeholder="Password">
    39                     </div>
    40                 </div>
    41                 <div class="form-group">
    42                     <div class="col-sm-offset-2 col-sm-10">
    43                         <button type="submit" class="btn btn-primary">登录</button>
    44                         <button type="submit" class="btn btn-success c2">注册</button>
    45                     </div>
    46                 </div>
    47             </form>
    48         </div>
    49     </div>
    50 </div>
    51 
    52 </body>
    53 </html>
    View Code

    index.html

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     6     <meta name="viewport" content="width=device-width">
     7     <title>Title</title>
     8 </head>
     9 <body>
    10 <h1>hello{{ username }}</h1>
    11 </body>
    12 </html>
    View Code

    cookie存储到客户端

    优点:数据存储在客户端。减轻服务端的压力,提高网站的性能

    缺点:安全性不高,在客户端很容易被查看或破解用户会话信息

    四、session的简单使用

    1、基本操作(需要掌握的)

    复制代码
    1、设置session值
        request.session["session_name"]="admin"
    2、获取session值
        session_name = request.session("session_name")
    3、删除session值
        del request.session["session_name"]  删除一组键值对
        request.session.flush()   删除一条记录
    4、检测是否操作session值
        if "session_name"  is request.session:
    复制代码

    其他操作

    复制代码
    5、get(key, default=None)
    

    fav_color = request.session.get('fav_color', 'red')

    6、pop(key)

    fav_color = request.session.pop('fav_color')

    7、keys()

    8、items()

    9、setdefault()

    10、flush() 删除当前的会话数据并删除会话的Cookie。
    这用于确保前面的会话数据不可以再次被用户的浏览器访问
    例如,django.contrib.auth.logout() 函数中就会调用它。

    11 用户session的随机字符串
    request.session.session_key

        </span><span style="color: #008000;">#</span><span style="color: #008000;"> 将所有Session失效日期小于当前日期的数据删除</span>
    

    request.session.clear_expired()

        </span><span style="color: #008000;">#</span><span style="color: #008000;"> 检查 用户session的随机字符串 在数据库中是否</span>
        request.session.exists(<span style="color: #800000;">"</span><span style="color: #800000;">session_key</span><span style="color: #800000;">"</span><span style="color: #000000;">)
    
        </span><span style="color: #008000;">#</span><span style="color: #008000;"> 删除当前用户的所有Session数据</span>
        request.session.delete(<span style="color: #800000;">"</span><span style="color: #800000;">session_key</span><span style="color: #800000;">"</span><span style="color: #000000;">)
    
        request.session.set_expiry(value)
            </span>*<span style="color: #000000;"> 如果value是个整数,session会在些秒数后失效。
            </span>*<span style="color: #000000;"> 如果value是个datatime或timedelta,session就会在这个时间后失效。
            </span>*<span style="color: #000000;"> 如果value是0,用户关闭浏览器session就会失效。
            </span>* 如果value是None,session会依赖全局session失效策略。</pre>
    
    复制代码

    2、流程解析图

    由于cookie会把所有的信息都保存在客户端,也就是浏览器上,这样会导致不安全,所以引用了session,但是只是单单的session也不好用,必须session和cookie配合这去用。

    session会把信息保存在服务端。

    session原理分析流程:

    {"sessionID":"dfhasdjfhkjlcn4352kjdsfhkjsd"}

    if  post:

      request.session["is_login"]=True

      request.session["user"]=username

      return redirect("/index/”)

    Django会做三件事:

      1、创建随机字符串。假如s="sdgsdfg4565dfgsdfgsdf" 

      2、 在django-session表中,添加一条记录

        django-session有三个字段,分别是:session_key,session_data,expire_data

          SQL: 语句: insert into django-session values (s,"{"IS_LOGON":True,"USER":egon}",12321)

      3、给浏览器设置sessionID:  obj.set_cookie("sessionID",s)  

    执行完之后重定向:

    /home/ ----> {"sessionID":"fasdlkfjsakdl324ada2adhdjlka99"}

    request.session.get("IS_LOGON",None)

    在django-session表中,进行查询:

    s=requset.COOKIE.get("sessionID")
    select session-data from django-session where session-key=s

    3、示例

    views.py

     1 def log_in(request):
     2 
     3     if request.method=="POST":
     4         username=request.POST['user']
     5         password=request.POST['pwd']
     6 
     7         user=UserInfo.objects.filter(username=username,password=password)
     8 
     9         if user:
    10             #设置session内部的字典内容
    11             request.session['is_login']='true'
    12             request.session['username']=username
    13 
    14             #登录成功就将url重定向到后台的url
    15             return redirect('/backend/')
    16 
    17     #登录不成功或第一访问就停留在登录页面
    18     return render(request,'login.html')
    19 
    20 
    21 
    22 
    23 def backend(request):
    24     print(request.session,"------cookie")
    25     print(request.COOKIES,'-------session')
    26     """
    27     这里必须用读取字典的get()方法把is_login的value缺省设置为False,
    28     当用户访问backend这个url先尝试获取这个浏览器对应的session中的
    29     is_login的值。如果对方登录成功的话,在login里就已经把is_login
    30     的值修改为了True,反之这个值就是False的
    31     """
    32 
    33     is_login=request.session.get('is_login',False)
    34     #如果为真,就说明用户是正常登陆的
    35     if is_login:
    36         #获取字典的内容并传入页面文件
    37         cookie_content=request.COOKIES
    38         session_content=request.session
    39 
    40         username=request.session['username']
    41 
    42         return render(request,'backend.html',locals())
    43     else:
    44         """
    45         如果访问的时候没有携带正确的session,
    46         就直接被重定向url回login页面
    47         """
    48         return redirect('/login/')
    49 
    50 
    51 
    52 def log_out(request):
    53     """
    54     直接通过request.session['is_login']回去返回的时候,
    55     如果is_login对应的value值不存在会导致程序异常。所以
    56     需要做异常处理
    57     """
    58     try:
    59         #删除is_login对应的value值
    60         del request.session['is_login']
    61         
    62         # OR---->request.session.flush() # 删除django-session表中的对应一行记录
    63 
    64     except KeyError:
    65         pass
    66     #点击注销之后,直接重定向回登录页面
    67     return redirect('/login/')
    View Code

    template

     1 ===================================login.html==================
     2 <!DOCTYPE html>
     3 <html lang="en">
     4 <head>
     5     <meta charset="UTF-8">
     6     <title>Title</title>
     7 </head>
     8 <body>
     9 
    10 <form action="/login/" method="post">
    11     <p>用户名: <input type="text" name="user"></p>
    12     <p>密码: <input type="password" name="pwd"></p>
    13     <p><input type="submit"></p>
    14 </form>
    15 
    16 
    17 </body>
    18 </html>
    19 
    20 
    21 ===================================backend.html==================
    22 
    23 <!DOCTYPE html>
    24 <html lang="en">
    25 <head>
    26     <meta charset="UTF-8">
    27     <title>Title</title>
    28 </head>
    29 <body>
    30 
    31 <h3>hello {{ username }}</h3>
    32 <a href="/logout/">注销</a>
    33 
    34 </body>
    35 </html>
    View Code

    4、session存储的相关配置

     (1)默认的是数据库配置:        

     1 1
     2 2
     3 3
     4 4
     5 5
     6 6
     7 7
     8 8
     9 9
    10 10
    11 11
    12 12
    13 13
    14 14
    15 Django默认支持Session,并且默认是将Session数据存储在数据库中,即:django_session 表中。
    16   
    17 a. 配置 settings.py
    18   
    19     SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默认)
    20       
    21     SESSION_COOKIE_NAME = "sessionid"                       # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
    22     SESSION_COOKIE_PATH = "/"                               # Session的cookie保存的路径(默认)
    23     SESSION_COOKIE_DOMAIN = None                             # Session的cookie保存的域名(默认)
    24     SESSION_COOKIE_SECURE = False                            # 是否Https传输cookie(默认)
    25     SESSION_COOKIE_HTTPONLY = True                           # 是否Session的cookie只支持http传输(默认)
    26     SESSION_COOKIE_AGE = 1209600                             # Session的cookie失效日期(2周)(默认)
    27     SESSION_EXPIRE_AT_BROWSER_CLOSE = False                  # 是否关闭浏览器使得Session过期(默认)
    28     SESSION_SAVE_EVERY_REQUEST = False                       # 是否每次请求都保存Session,默认修改之后才保存(默认)
    View Code

    (2)缓存配置

     1 a. 配置 settings.py
     2   
     3     SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
     4     SESSION_CACHE_ALIAS = 'default'                            # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
     5   
     6   
     7     SESSION_COOKIE_NAME = "sessionid"                        # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串
     8     SESSION_COOKIE_PATH = "/"                                # Session的cookie保存的路径
     9     SESSION_COOKIE_DOMAIN = None                              # Session的cookie保存的域名
    10     SESSION_COOKIE_SECURE = False                             # 是否Https传输cookie
    11     SESSION_COOKIE_HTTPONLY = True                            # 是否Session的cookie只支持http传输
    12     SESSION_COOKIE_AGE = 1209600                              # Session的cookie失效日期(2周)
    13     SESSION_EXPIRE_AT_BROWSER_CLOSE = False                   # 是否关闭浏览器使得Session过期
    14     SESSION_SAVE_EVERY_REQUEST = False                        # 是否每次请求都保存Session,默认修改之后才保存
    View Code

    (3)文件配置

     1 a. 配置 settings.py
     2   
     3     SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
     4     SESSION_FILE_PATH = None                                    # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()        
     5     SESSION_COOKIE_NAME = "sessionid"                          # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串
     6     SESSION_COOKIE_PATH = "/"                                  # Session的cookie保存的路径
     7     SESSION_COOKIE_DOMAIN = None                                # Session的cookie保存的域名
     8     SESSION_COOKIE_SECURE = False                               # 是否Https传输cookie
     9     SESSION_COOKIE_HTTPONLY = True                              # 是否Session的cookie只支持http传输
    10     SESSION_COOKIE_AGE = 1209600                                # Session的cookie失效日期(2周)
    11     SESSION_EXPIRE_AT_BROWSER_CLOSE = False                     # 是否关闭浏览器使得Session过期
    12     SESSION_SAVE_EVERY_REQUEST = False                          # 是否每次请求都保存Session,默认修改之后才保存
    View Code
  • 相关阅读:
    iSCSI又称为IPSAN
    文档类型定义DTD
    HDU 2971 Tower
    HDU 1588 Gauss Fibonacci
    URAL 1005 Stone Pile
    URAL 1003 Parity
    URAL 1002 Phone Numbers
    URAL 1007 Code Words
    HDU 3306 Another kind of Fibonacci
    FZU 1683 纪念SlingShot
  • 原文地址:https://www.cnblogs.com/maaosheng/p/11621521.html
Copyright © 2011-2022 走看看