• 011---Djang的cookie和session



    -------------------------------------------------------------cookie与session----------------------------------------------------------

    前面已经说过http协议无法保存状态,但是实际使用场景,我们又却要保存状态,因此cookie就诞生了,会话跟踪技术。

    定义:保存在浏览器本地的key value(键值对)。类似python的字典。翻译成中文就是小饼干的意思。

    工作原理:由服务器产生内容,浏览器收到响应后保存在本地,当浏览器再次访问时,浏览器会自动携带cookie,服务器就能判断这个是谁了。

    发展:虽然一定程度上解决了'保持登录的状态',但是cookie本身最大只支持4096b,而且cookie是保存在浏览器本地的,有些用户敏感内容、私密信息存起来也不好,随时可拦截和窃取。因此就需要一种新的东西, 支持更大的字节。且不是保存在浏览器本地,而是保存在服务器。有较高的安全性,它就是session。

    注意:
    session和cookie不限于django。不限于语言和框架。其实是共通性的东西。
    不同浏览器无法共享cookie,也就是换个浏览器,cookie是不一样的。
    多次登录,同一个浏览器的cookie会覆盖之前的记录

    先来写一个cookie版的登录
    视图部分:

     1  def login(request):
     2         if request.method == "POST":
     3             user = request.POST.get('user')  # 获取用户名
     4             pwd = request.POST.get('pwd')    # 获取密码
     5             user = models.UserInfo.objects.filter(name=user, pwd=pwd).first()  # 数据库查找
     6 
     7             # 如果有这个用户
     8             if user:
     9                 # 登录成功
    10                 # 创建响应对象:HttpResponse()  or  render(request,...)  or redirect() 三个都可以
    11                 response = HttpResponse('ok')
    12 
    13                 # 设置cookie
    14                 response.set_cookie('is_login', True)       # 浏览器保存形式:{"is_login":true}
    15                 response.set_cookie('user', user.name, )    # 浏览器保存形式:{"user":用户的名字}
    16                 return response
    17 
    18         return render(request, 'login.html')

    模版部分:
     1  <!DOCTYPE html>
     2         <html lang="zh_CN">
     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, initial-scale=1">
     7             <title>Title</title>
     8         </head>
     9         <body>
    10 
    11         <form action="" method="post">
    12             {% csrf_token %}
    13             用户名:<input type="text" name="user">
    14             密码:<input type="password" name="pwd">
    15             <input type="submit" value="登录">
    16 
    17         </form>
    18         </body>
    19         </html>

    再写一个index视图。如果不设置cookie的话,用户是可以直接访问的。
    视图部分:
     1  def index(request):
     2             # 获取cookie
     3             is_login = request.COOKIES.get('is_login')
     4             name = request.COOKIES.get('user')
     5 
     6             # 如果is_login为空,重定向到login页面
     7             if not is_login:
     8                 return redirect('/login/')
     9              # 登录成功就返回index页面
    10             return render(request, 'index.html', {"username": name})
        模版部分:
     1         <!DOCTYPE html>
     2         <html lang="zh_CN">
     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, initial-scale=1">
     7             <title>Title</title>
     8         </head>
     9         <body>
    10 
    11         <h1>this is index</h1>
    12         <h3>Hello {{ username }}</h3>
    13         <p>上次登录时间:{{ last_time }}</p>
    14 
    15         <a href="/logout_session/">注销</a>
    16         </body>
    17         </html>


    先不登录访问index一下:
    可以看到自动跳转到login页面了。因为没登陆,获取不到cookie。


    现在登陆:
    登录成功后


    可以看到浏览器保存了cookie

    再次访问index


    写注销视图logout
    1 def logout(request):
    2         response = redirect('/login/')
    3         # 清除cookie
    4         response.delete_cookie(key='is_login')
    5         return response

    访问/logout/后,会自动跳转到logim登录页面


    再此访问index。cookie清理了。会自动跳转到login登录。


    session版登录
    视图部分:
    基本和cookie一样就是设置的方式不一样
    def login_session(request):
                if request.method == 'POST':
                    username = request.POST.get('user')
                    pwd = request.POST.get('pwd')
                    user = models.UserInfo.objects.filter(name=username, pwd=pwd).first()
                    if user:
                        request.session['is_login'] = True
                        request.session['username'] = username
                        '''
                        三步:
                            如果已经访问过一次,有session_id就是更新操作。并不是登录一次创建一次,并不是创建
                            1、服务器生成一个随机字符串xxx
                            2、response.set_cookie('session_id','xxx')
                            3、在django_session表中创建一条记录:
                                session-key     session-data                           过期时间
                                xxx             {'is_login':True,'username':username}
                        '''
    
                        return HttpResponse('登录成功')
                return render(request, 'login.html')




    index视图
     1  def index_session(request):
     2         is_login = request.session.get('is_login')
     3         print(is_login)
     4         '''
     5         1、request.COOKIES.get('session_id')  # 得到随机字符串
     6         2、在django-session表中过滤记录
     7             obj = django-session.objects.filter(session-key=xxx).first()
     8         3、obj.session-data.get('is_login')
     9         '''
    10         if is_login:
    11             username = request.session.get('username')
    12             last_time = request.session.get('last_time')
    13             return render(request, 'index.html', {"username": username, "last_time": last_time})
    14         return render(request, 'login.html')

    logout注销视图
    1     def logout_session(request):
    2         response = redirect('/login_session/')
    3         request.session.flush()  # 删除当前会话的数据和cookie
    4         return response
    总结:
    cookie:
        1、设置cookie  response.set_cookie(key,value)
        2、读取cookie  request.COOKIES.get(key)
        3、删除cookie  response.delete_cookie(key)
    
        设置和删除都是response  读取是request
    
    session
        1、设置:request.session[key]=value
        2、读取:request.session.get(key)
        3、删除:request.session.flush()
    
        都是request
  • 相关阅读:
    DDD~大话目录
    基于DDD的.NET开发框架-DDD经典分层
    补习知识:Entity Framework Code First属性映射约定
    一个官翻教程集合:ASP.NET Core 和 EF Core 系列教程
    补知识:EntityFramework Core映射关系详解
    关于this的问题
    promise
    js的类型转换
    不要在块内声明一个函数
    let和var
  • 原文地址:https://www.cnblogs.com/xjmlove/p/9921440.html
Copyright © 2020-2023  润新知