zoukankan      html  css  js  c++  java
  • [oldboy-django][2深入django]cookies + session

    1.1 cookies

    - 初识cookie
            a.cookie是保留在浏览器端的键值对
            b.服务端可以向客户端写cookie
            c.客户端每次发送请求,会携带cookie一起发送过去,而且cookie是存放在消息头cookie字段
    
            应用:
                a. 投票
                b. 用户登录
    
            深入cookie
                    -- 登录页面处理:
                        obj = redirect('/classes/')
                        obj.set_cookies('crsf','lzp', max-age=10, expires=value)
                        return obj
    
                    -- classes页面
                        cookies = request.COOKIES
                        if not cookies:  # 这里只是简单判断是否有cookie,并没有判断cookie是否正确
                            redirect('/login/')
    View Code

    1.2 设置cookies

    -- 设置cookie
                obj.set_cookies(key, value, max-age=None, expires=None, path='/', ...)
            - 参数
                a. key
                b. value
                c. max-age=None
                     # mag-age=10表示当超过10s,浏览器会自动清除该cookie
                d. expires=None
                     # expires也是cookie的保存时间,不过是日期类型,而不是整数
                     # expires 和 max-age只要一个就好,推荐max-age(因为设置expires,最后还是转换成max-age)
    
                e. path='/’
                    #表示只有访问path路径的时候才能拿到cookies
                    #当path='/'表示所有路径(url)都可以拿到cookies
    
                f. domain=None,默认是当前域名
    
                h. secure=False,
                    secure=True,https传输
    
                i. httponly=False 只能http传输
    
    
            - set_cookie后会在响应头里面增加一个Set-cookie字段,这个字段的值是一个字典
    
                key为set_cookie里面的kye,value为set_cookie里面的value
                    obj.set_cookie('ticket3', '3')
                之前的key,value也会保存在浏览器中
                    obj.set_cookie('ticket4', '4')
    
            - 下次访问的时候,会将浏览器保存的cookie存放在消息头Cookie上
                Cookie:ticket3=3; ticket4=3
    View Code

    1.3 设置签名cookies

        -- 签名设置cookie(加盐)
            a. 设置签名cookie:
                # obj.set_signed_cookie('tt1','33',salt='ddddd')
                得到一个cookie: 'tt': '33:1e8HKP:CiklYZU3LtBdztFrCWB7PfEvBbM'
            b. 获取签名
                request.get_signed_cookie('tt1',salt='ddddd')
    View Code

    1.4 cookies实现登录验证

    -- 装饰器,实现登录验证
            # views
                def login(request):
                    if request.method == "GET":
                        return render(request, "login.html")
                    else:
                        username = request.POST.get('username')
                        pwd = request.POST.get('password')
                        remember = request.POST.get('remember')
                        # username:root,pwd:123;remember:on
                        if username == 'root' and pwd == '123':
                            # 设置一个cookie,返回给客户端,然后这个cookie会随着请求一起
                            obj = redirect('/classes/')
                            obj.set_cookie('ticket', 'lzp')
                            return obj
                        else:
                            return redirect('/login/')
    
            # 装饰器(登录状态验证)
                def auth(func):
                    def wrapper(request):
                        ticket = request.COOKIES.get('ticket')
                        print(ticket)
                        if not ticket:
                            return redirect('/login/')
                        else:
                            return func(request)
    
                    return wrapper
    
            # 使用装饰器登录验证(不能直接方法/classes/ 必须先登录才能访问/classes/
                @auth
                def classes(request):
                    # 先要判断用户是否成功,通过cookie, cookie是一个字典, ticket是自己设置的一个key
                    # ticket = request.COOKIES.get('ticket')
                    # print(ticket)
                    # if not ticket:
                    #     return redirect('/login/')
                    # pymysql操作数据库
                    print('ddddd')
                    conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='django_student', charset='utf8')
                    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
                    cursor.execute("select id,title from class")
                    class_list = cursor.fetchall()
                    cursor.close()
                    conn.close()
    
                    return render(request, "classes.html", {"class_list": class_list})
    View Code


    2.1 session

        - session定义
            1 cookie:
                保存在客户端的键值对, 依赖cookie,用来保持会话,记住登录状态;敏感信息不会直接给用户
            2 session:
                保存在服务端的数据(本质上是键值对)
            3 session原理:
                每一个用户登录成功后,服务端生成一个属于该用户的随机字符串,
                并把这个随机字符串作为字典的Key,
                往这个key添加该用户的敏感信息; 并将该随机字符串作为response_cookies 中sessionid返回给客户端。
                客户发送下一个请求的时候,携带该随机字符串,服务端在字典找到该随机字符串,就会记得该用户的登录状态。
                好处:敏感信息没有给客户端; 依赖cookie,保持会话
    View Code

    2.2 session使用

    - session使用
            获取:
                request.session.get('k1',None)
                request.session['k1']
    
            设置:
                request.session['k1'] = '123'
                request.session.setdefault('k1','123') # 存在则不设置
    
            删除:
                del request.session['k1']
    
            获取当前用户所有键值对
                request.session.keys()
                request.session.values()
                request.session.items()
    
            获取当前用户随机字符串:
                request.session.session_key
    
            删除当前用户的session
                request.session.delete(request.session.session_key)
    
            检查用户的随机字符串是否在数据库中
                request.session.exist(request.session.session_key)
    
            将数据库中所有的session,有效时间(django_session中的expire_date字段)小于当前时间的数据删除
                request.session.clear_expired()
                # 客户端中cookie中sessionid默认是保存两周
                # django_session中expire_date默认也是两周
    
            设置session超时时间(同时设置客户端session和服务端session)
                request.session.set_expiry(value)
                    # 如果value是个整数,session会在些秒数后失效。
                    # 如果value是个datatime或timedelta,session就会在这个时间后失效。
                    # 如果value是0,用户关闭浏览器session就会失效。
                    # 如果value是None,session会依赖全局session失效策略。
    View Code

    2.3 session服务端保存位置设置

    - 配置session(session默认是保存数据库表django_session)
    
            1 数据库session
                Django默认支持Session,并且默认是将Session数据存储在数据库中,即:django_session 表中。
                a. 配置 settings.py
                    SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默认)
                    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,默认修改之后才保存(默认)
    
            2 缓存session
                a. 设置settings.py
                    SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
                    SESSION_CACHE_ALIAS = 'default'                            # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
    
            3 文件session
                a. 设置settings.py
                        SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
                        SESSION_FILE_PATH = None                                    # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()
    View Code

    2.4 基于session登录验证

        - 基于session的登录验证
            a. views
                def login(request):
                    if request.method == 'GET':
                        return render(request, 'app02_login.html')
    
                    else:
                        username = request.POST.get('username')
                        pwd = request.POST.get('pwd')
                        models.User.objects.filter()
                        obj = models.User.objects.filter(name=username,password=pwd).first()
                        if obj:
                            #1 生成随机字符串
                            #2 返回随机字符串给客户端(通过cookie)
                            #3 服务端保存该随机字符串()
                            #4 服务端保存形式:
                            # {
                            #     '随机字符串':{'username': 'root', 'email': 'root1234@qq.com'}
                            # }django是保存在数据库表django_session中
                            request.session['username'] = obj.name
                            request.session['email'] = obj.email
                            return redirect('/app02/index.html')
                            # 客户端得到session(随机字符串)后,后面的请求都会携带在cookie中sessionid中
                        else:
                            return render(request, 'app02_login.html', {'msg': '用户名或密码错误'})
    
    
                def index(request):
                    # 获取cookie中的sessionid(即随机字符串)
                    # 在数据库表django_session查找是否有随机字符串
                    # 如果在数据库表中,判断username该列是否有值(如果有值代表登录成功)
                    v = request.session.get('username')
                    if v:
                        return HttpResponse('登录成功:%s'% v)
                    else:
                        redirect('/app02/login.html')
    
            b. 模板
                <body>
                    <h3>用户登录</h3>
                    <form action="/app02/login.html" method="POST">
                        {% csrf_token %}
                        <p><input type="text" placeholder="username" name="username"></p>
                        <p><input type="password" placeholder="password" name="pwd"></p>
                        <p><input type="submit" value="login"></p>
                        <p style="color:red">{{ msg }}</p>
                    </form>
                </body>
    View Code



    3.1 cookies 与session比较

        - session 和cookie 比较
            同: cookie和session都是用来记住登录状态
            异:
                cookie是将用户的唯一标识是保存在客户端中,不安全;
                cookie有添加一个签名,将唯一标识进行加密;但是可以破解,仍然不是很安全
    
                session:只给客户端发送一个字符串,并不包含任何标识用户的内容
                在服务端内存保存一个键值对,
                    {'随机字符串': {'name': '于浩'}}
                当客户端发送下一个请求,并携带随机字符串,服务端获取字符串,并在内存中判断
                唯一标识来判断用户是否已经登录了
    View Code
  • 相关阅读:
    [LeetCode]题解(python):086
    [LeetCode]题解(python):083
    [LeetCode]题解(python):082
    两位图灵奖得主万字长文:新计算机架构,黄金十年爆发!——读后感
    《架构漫谈》阅读笔记三
    以《淘宝网》为例,描绘质量属性的六个常见属性场景
    周学习笔记(01)——大三下
    Anconda、Pycharm下载、安装、配置教程(极其详细)
    《架构漫谈》阅读笔记二
    《架构漫谈》阅读笔记一
  • 原文地址:https://www.cnblogs.com/liuzhipenglove/p/7751174.html
Copyright © 2011-2022 走看看