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

    在一个会话的多个请求中共享数据,这就是会话跟踪技术。例如在一个会话中的请求如下:  请求银行主页; 

    • 请求登录(请求参数是用户名和密码);
    • 请求转账(请求参数与转账相关的数据); 
    • 请求信誉卡还款(请求参数与还款相关的数据)。  

    在这上会话中当前用户信息必须在这个会话中共享的,因为登录的是张三,那么在转账和还款时一定是相对张三的转账和还款!这就说明我们必须在一个会话过程中有共享数据的能力。

    会话一定是反复的沟通,至于多少次,没有上限!

    HTTP是无状态保存
    简单来讲,HTTP要求浏览器对服务器的请求,每一个请求,对于服务器而言,都是新的请求
    服务器,并不知道浏览器是谁。

    2. 会话路径技术使用Cookie或session完成 

    我们知道HTTP协议是无状态协议,也就是说每个请求都是独立的!无法记录前一次请求的状态。但HTTP协议中可以使用Cookie来完成会话跟踪!在Web开发中,使用session来完成会话跟踪,session底层依赖Cookie技术.

    什么叫Cookie 

    Cookie是key-value结构,类似于一个python的字典 ,随着服务器端的响应发送给客户端浏览器,然后客户端浏览器会把Cookie保存起来,当下一次访问服务器时把cookie再发给服务器.

    cookie是由服务器创建,然后通过响应发送给客户端的一个键值对

    客户端会保存Cookie,并会标记出Cookie的来源(哪个服务器)

    当客户端想服务器发出请求时会把所有这个服务器的Cookie包 在请求中发送给服务器,这样服务器就可以识别客户端

    Cookie规范 

    •  Cookie大小上限为4KB; 
    •  一个服务器最多在客户端浏览器上保存20个Cookie; 
    •  一个浏览器最多保存300个Cookie;  

    每一个客户端浏览器,都有一个cookie容器。

    cookie:针对一个服务器,保存在客户端某一个浏览器上的key-value存储的数据结构中

    服务器有权利向浏览器写入cookie
    一旦写入cookie,那么下次访问,会带着cookie去访问服务器

    比如电脑的谷歌浏览器和火狐浏览器,各自有独立的cookie容器,不能相互访问!

    request是客户端请求,response是服务端响应。
    读取客户端的cookies要用request的,但是要写入客户端cookies就要用response

    urls.py

    urlpatterns = [
        # url(r'^admin/', admin.site.urls),
        url(r'^login/', views.login),
        url(r'^index/', views.index),
    ]

    views.py

    from django.shortcuts import render, HttpResponse, redirect
    from django.urls import reverse
    import datetime
    
    # Create your views here.
    def index(request):
        print(request.COOKIES)  # 打印cookie
        is_login = request.COOKIES.get("is_login")
        if not is_login:
            return redirect("/login/")
        username =request.COOKIES.get("username")#获取cookies的username值
        time=request.COOKIES.get("login_time")
        return render(request, "index.html",{"username":username,"login_time":time})
    
    def login(request):
        if request.method == "POST":
            user = request.POST.get("user")
            pwd = request.POST.get("pwd")
            if user == "zaizai" and pwd == "123":
                obj = redirect("/index/")  # 302重定向登陆页面
                # obj.set_cookie("is_login", True)
                obj.set_cookie("is_login", True, 5)  # cookie设置登陆状态  设置为5秒钟,cookie失效
                obj.set_cookie("username", user, 5)  # cookie设置用户名
                #获取当前时间
                now=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                obj.set_cookie("login_time",now)
                return obj
        return render(request, "login.html")

    login.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <form action="" method="post">
        {% csrf_token %}
        <lable>用户名</lable>
        <input type="text" name="user">
        <lable>密码</lable>
        <input type="password" name="pwd">
        <input type="submit">
    </form>
    </body>
    </html>

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h3>{{ username }}个人首页,登陆时间{{ login_time }}</h3>
    </body>
    </html>

    跳转首页后,疯狂的刷新页面。5秒后,会自动调转到登录页面

    效果如下:

    二、session

    服务器技术,为每一个用户的浏览器创建了一个独享的session对象,由于session为用户浏览器独享

    所以用户在访问服务器web资源时,可以把各自的数据放在各自的session中

    当用户在访问其他资源,其他web资源在从用户各自session中去除数据为用户服务

    session要比cookie用的更多,因为cookie不安全!
    session是基于cookie开发的。思路和cookie是不一样的
    它们之间最大的不同在于,session存在服务器。而cookie存储在浏览器中!

     session给cookie一把钥匙,
    cookie只存钥匙。通过钥匙,进入session仓库,取东西。

    request.session['session_name'] = "admin"
    1. 生成随机字符串 1s813eub...
    2. django-session表中生成一条记录
    +-------------+--------------+----------------------------+
    | session_key | session_data | expire_date                |
    +-------------+--------------+----------------------------+
    | 1s813eub...  | ZWU0MD...    | 2018-07-18 12:49:52.143483 |
    +-------------+--------------+----------------------------+
    session_data原始数据是这样的{"is_login":True,"username":"xiao","login_time":"2018-07-04 11:49:52"}
    存表时,做了加密存储
       
    3. 响应体.set_cookie("sessionid","1s813eub...")  

    上面一行代码执行是,会生成钥匙给浏览器,并存储在服务器上
    存储在django_session表中

    执行2个命令,生成django需要的表

    python manage.py makemigrations
    python manage.py migrate

    打开django_session表,它只有3个字段

    session_key:这个是客户端保存的钥匙
    session_data: 这个是session数据,比如{"username":"xiao"}。它会将数据加密后保存!
    expire_date:有效期

    session_key是随机的。这个session是django封装的,

    在表中,能通过key取到session_data,说明是登录过的。否则没有登录!

    django中session语法

    1、设置Sessions值
              request.session['session_name'] ="admin"
    2、获取Sessions值
              session_name = request.session["session_name"]
    3、删除Sessions值
              del request.session["session_name"]
    4、flush()
         删除当前的会话数据并删除会话的Cookie。
         这用于确保前面的会话数据不可以再次被用户的浏览器访问

    views.py

    def login_session(request):
        if request.method == "POST":
            user = request.POST.get("user")
            pwd = request.POST.get("pwd")
            if user == "xiao" and pwd == "123":
                # 写session
                request.session['is_login'] = True  # session设置登录状态
                request.session['username'] = user # session设置用户名
                now = datetime.datetime.now().strftime("%Y-%m-%d %H:%I:%S")
                request.session['login_time'] = now
                return redirect("/index_session/")  # 302重定向到首页
        return render(request,"login.html")
    
    def index_session(request):
        is_login = request.session.get("is_login")  # 从session中获取登录状态
        if not is_login:  # 判断状态不是True时
            return redirect("/login_session/") # 302重定向到登录页面
    
        username = request.session.get("username")  # 从session中获取用户名
        login_time = request.session.get("login_time")  # 从session中获取登录时间
    
        return render(request, "index.html", {"username": username, "login_time": login_time})
    def logout(request):
        request.session.flush()#清理session
        return redirect("/login_session")

    login.html

    <body>
    <form action="" method="post">
        {% csrf_token %}
        <lable>用户名</lable>
        <input type="text" name="user">
        <lable>密码</lable>
        <input type="password" name="pwd">
        <input type="submit">
    </form>
    </body>
    </html>

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h3>{{ username }}个人首页,登陆时间{{ login_time }}</h3>
    <p><a href="/logout/">注销</a></p>
    </body>
    </html>

    登陆成功后

     

    http://127.0.0.1:8000/index_session/  不过期就可以一直访问 无须再次输入密码

    request.session.flush() 它到底执行了啥呢?

    它执行了3个步骤:

    1. 浏览器发送请求时,将cookie发送给服务器,服务器获取key为sessionid的值

    2. 在服务器的django-session表中查询session_key=sessionid值。并执行delete操作,删除一条记录。

    3. 将浏览器cookie中的sessionid删除掉

    总结:cooke和session的区别

    cookie实际,就是一个字符串的字典数据,存储在浏览器中。

    cookie只能有4K

    存储在浏览器中,它是由服务器响应体中的Set-Cookie来设置的

    浏览器能从cookie中获取数据,有安全隐患

    session是存储在服务端,它会加密存储。

    session是基于cookie来做的。浏览器保存key,也就是sessionid。如果服务器有脏数据,会在14天后删除。

    cookie中,有设置加密的方法。比如:set_signed_cookie(),有兴趣的,可以了解一下!

    作业

    ef user(f):
        def inner(*args, **kwargs):
            request = args[0]  # 响应请求
            is_login = request.session.get("is_login")
            print(is_login)
            print(request)
            if request.session.get("is_login"):
                return f(*args, **kwargs)
            else:
                return redirect("/login_def/")
        return inner
    
    def login_def(request):
        # print('111111',request)
        if request.method == "POST":
            user = request.POST.get("user")
            pwd = request.POST.get("pwd")
            if user == "xiao" and pwd == "123":
                # 写session
                request.session['is_login'] = True  # session设置登录状态
                request.session['username'] = user  # session设置用户名
                now = datetime.datetime.now().strftime("%Y-%m-%d %H:%I:%S")
                request.session['login_time'] = now
                print(user)
                return redirect("/index_def/")  # 302重定向到首页
        return render(request, "login.html")
    
    
    @user
    def index_def(request):
        # is_login = request.session.get("is_login")  # 从session中获取登录状态
        # if not is_login:  # 判断状态不是True时
        #     return redirect("/login_session/") # 302重定向到登录页面
        username = request.session.get("username")  # 从session中获取用户名
        print(username)
        login_time = request.session.get("login_time")  # 从session中获取登录时间
        return render(request, "index.html", {"username": username, "login_time": login_time})
  • 相关阅读:
    input file 多张图片上传 获取地址 ——fileReader
    15个常用的javaScript正则表达式
    sublime-emmet
    AMD-requireJS
    jQuery-lazyload参数
    easyui 查询条件form 数据遍历
    导出excel设置金额格式
    html5页面添加时间戳
    创建枚举
    定义实体转json需要方法
  • 原文地址:https://www.cnblogs.com/zaizai1573/p/10491343.html
Copyright © 2011-2022 走看看