Django的Session和cookie

Session和cookie

  • 参考文献: https://www.cnblogs.com/wupeiqi/articles/5246483.html

1.问题引入

1.1 cookie是什么?

  • 保存在客户端浏览器上的键值对

1.2 Sessions

  • 保存在服务端的数据(本质上是键值对)
  • 应用:依赖 Cookie
  • 作用:保持会话(web网站)
  • 好处:敏感信息不会直接给客户端

; 1.3 简单示例

2.cookie

  • cookie进行维持会话,一个浏览器只能存储 20个cookie,服务端上限为 300cookie
  • 注意:cookie大小不能超过 4kb
  • cookie一般 *不会设置中文

2.1 简单应用

  • 登录界面设置cookie防止其他非登录界面的人员进行访问
from django.shortcuts import render,redirect,HttpResponse

def index(request):
    if request.COOKIES.get('is_login')=='True':
        return render(request,'index.html')
    else:
        return HttpResponse('你没成功!')

def login(request):
    if request.method=='GET':
        return render(request,'login.html')
    if request.method=='POST':
        username=request.POST.get('username')
        pwd=request.POST.get('pwd')
        if username=='aaa' and pwd=='666':
            ret=redirect('index')

            ret.set_cookie('is_login',True)
            print('访问成功')
            return ret
        else:
            return redirect('login')
  • 注意:cookie虽然可以实现登录的验证,但是会将状态设置在客户端浏览器,因此并不安全。

2.2 cookie的分发与验证

  • 使用装饰器进行封装cookie的分发与验证
  • *装饰器的简单复习

def wapper(f):

    def inner(request,*args,**kwargs):

        ret=f(*args,**kwargs)

        return ret
    return inner

@wapper
def test():
    pass

'''
知识点
函数内部定义一个函数,该函数要调用一下原函数的参数
最外层函数的返回值为内层函数
装饰器的调用
@name
*************
装饰器与Python 的闭包相关联,且知识点与js的函数参数可以为函数高度相似
'''
  • *装饰器的cookie
from django.shortcuts import render,redirect,HttpResponse

def wapper(f):
    def inner(request,*args,**kwargs):
        is_loin=request.COOKIES.get('is_login')
        if is_loin=='True':
            ret=f(request,*args,**kwargs)
            return ret
        else:
            return redirect('login')
    return inner

@wapper
def index(request):
    return render(request,'index.html')

def login(request):
    if request.method=='GET':
        return render(request,'login.html')
    if request.method=='POST':
        username=request.POST.get('username')
        pwd=request.POST.get('pwd')
        if username=='aaa' and pwd=='666':
            ret=redirect('index')
            ret.set_cookie('is_login',True)

            return ret
        else:
            return redirect('login')

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登陆界面title>
head>
<body>

    <h1>前进,前进,不择手段的前进h1>
    <hr>
    <form method="post" action="">
        {% csrf_token %}
        用户名:<input type="text" name="username">

        密码:<input type="password" name="password">
        <button type="submit">提交button>
    form>
body>
html>

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
<h1>自然选择,前进四h1>
body>
html>

2.3设置cookie的有效期

ret.set_cookie('name', 'AA',10)
ret.set_cookie('sex', 'male',10)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NyjmwOte-1641355361965)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210326221531916.png)]

2.5 cookie的其他设置

rep = HttpResponse(...) 或 rep = render(request, ...)

rep.set_cookie(key,value,...)
rep.set_signed_cookie(key,value,salt='加密盐',...)
    参数:
        key,              键
        value='',         值
        max_age=None,     超时时间
        expires=None,     超时时间(IE requires expires, so set it if hasn't been already.)
        path='/',         Cookie生效的路径,/ 表示根路径,特殊的:跟路径的cookie可以被任何url的页面访问
        domain=None,      Cookie生效的域名
        secure=False,     https传输
        httponly=False    只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)

2.6 cookie的缺点

  • cookie键值对存在与本地的浏览器文件安全性较低

例如

def login(request):
    if request.method=='GET':
        return render(request,'login.html')
    if request.method=='POST':
        username=request.POST.get('username')
        pwd=request.POST.get('pwd')
        if username=='aaa' and pwd=='666':
            ret=redirect('index')
            ret.set_cookie('is_login',True)
            ret.set_cookie('name', 'AA')
            ret.set_cookie('sex', 'male')

            return ret
        else:
            return redirect('login')

Django的Session和cookie

3.seesion会话

  • session的相关 数据(键值对) 默认存储在服务端的数据库中 django_session表中。
  • 一个用户,一个浏览器只保存一条记录
  • seesion的默认过期时间是 两周,可以手动设置
  • 生成cookie为加密后的字符串,数据存储在 django_session数据表之中
  • 可以在setting-global里面修改seesion_id的名称,与数据库表中的键相对应。

; 3.1 一般使用

def login(request):
    """ 用户名和密码登录 """
    if request.method == 'GET':
        form = LoginForm(request)
        return render(request, 'login.html', {'form': form})
    form = LoginForm(request,data=request.POST)
    if form.is_valid():

        username = form.cleaned_data['username']
        password = form.cleaned_data['password']

        '''
            查询逻辑:username=手机号或者是邮箱,但是验证码均等于验证码
                    (username=moblie_phone and password=password)or(username=email and password=password)
            属于复杂查询条件,因此使用orm的Q查询
        '''
        user_obj = models.UserInfo.objects.filter(Q(email=username) | Q(moble_phone=username)).filter(
            password=password).first()
        if user_obj:
            '''登录成功为1'''

            request.session['username'] = user_obj.username

            request.session.set_expiry(60 * 60 * 24 * 14)
            return redirect('home')

        form.add_error('username', '用户名或密码错误')
    return render(request, 'login.html', {'form': form})

3.2session和cookie的有效期

  • seesion的默认过期时间是两周,可以手动设置
request.session.set_expiry(60 * 60 * 24 * 14)
  • 逻辑可参考上述(一般使用)代码

Django的Session和cookie
from django.shortcuts import render,redirect,HttpResponse

def index(request):

    '''
        1.从cookie里面拿出了session_id:xxx随机字符串拿出来
        2、去django-session表里面查询到相对应的数据
        3.反解密用户存储的数据,并获取用户的数据
    '''
    is_login = request.session.get('is_login')
    if is_login==True:
        return render(request,'index.html')
    else:
        return redirect('home')
def login(request):
    if request.method=='GET':
        return render(request,'login.html')
    if request.method=='POST':
        username=request.POST.get('username')
        pwd=request.POST.get('password')
        if username=='aa' and pwd=='300':

            request.session['is_login']=True
            request.session['name']='AA'
            '''
                1、生成ssesion_id:随机字符串
                2、在COOKIE里面加上了键值对:session_id:ZDsrf
                3.将用户的数据进行加密并保存到DJANGO-SESSION表里面,形式为一条记录
                # 数据库中session_key  随机字符串
                # seesion_data:用户加密的数据

            '''
            return redirect('index')
        else:
            return HttpResponse('请正常登录')

3.3 seession的装饰器

装饰器函数一般要写在被装饰函数的上方,以免语法错误

def session_author(fn):

    def inner(request,*args,**kwargs):
        status=request.session.get('is_login')
        if status:
            ret=fn(request)
            return ret
        else:

            return redirect(reverse('login'))
    return inner

与cookie的装饰器相似。

  • 注: 上述装饰器可用作判断用户是否登录,但是在 django中使用较少。django中一般使用中间件判断用户是否登录。并设置对应的白名单。

3.4 Session操作。

  • 可以进行增删改查。
  • 增加就是登录时的写入,修改可以直接像字典一样进行修改。
  • 删除seesion
def logout(request):

    request.session.flush()
    return redirect('home')

常用作用户注销登录的实现。
* 获取seesion 中间件中获取判断

class AuthMiddleware(MiddlewareMixin):

    def proccess_request(self,request):中
        '''如果用户已登录,则request中赋值'''
        user_name=request.session.get('user_name',0)

        userobj=models.UserInfo.objects.filter(user_name=user_name)

        request.tracer=userobj

  • 完整登录中间件模板

import datetime
from django.shortcuts import redirect
from django.utils.deprecation import MiddlewareMixin
from django.conf import settings

from web import models

class Tracer(object):

    def __init__(self):
        self.user = None
        self.price_policy = None
        self.project = None

class AuthMiddleware(MiddlewareMixin):

    def process_request(self, request):
        """ 如果用户已登录,则request中赋值 """

        request.tracer = Tracer()

        user_id = request.session.get('user_id', 0)
        user_object = models.UserInfo.objects.filter(id=user_id).first()
        request.tracer.user = user_object

"""
        1. 获取当用户访问的URL
        2. 检查URL是否在白名单中,如果再则可以继续向后访问,如果不在则进行判断是否已登录
"""
        if request.path_info in settings.WHITE_REGEX_URL_LIST:
            return

        if not request.tracer.user:
            return redirect('login')

        _object = models.Transaction.objects.filter(user=user_object, status=2).order_by('-id').first()

        current_datetime = datetime.datetime.now()
        if _object.end_datetime and _object.end_datetime < current_datetime:
            _object = models.Transaction.objects.filter(user=user_object, status=2, price_policy__category=1).first()

        request.tracer.price_policy = _object.price_policy

"""
        # 获取当前用户ID值最大(最近交易记录)
        _object = models.Transaction.objects.filter(user=user_object, status=2).order_by('-id').first()

        if not _object:
            # 没有购买
            request.price_policy = models.PricePolicy.objects.filter(category=1, title="个人免费版").first()
        else:
            # 付费版
            current_datetime = datetime.datetime.now()
            if _object.end_datetime and _object.end_datetime < current_datetime:
                request.price_policy = models.PricePolicy.objects.filter(category=1, title="个人免费版").first()
            else:
                request.price_policy = _object.price_policy
"""

    def process_view(self, request, view, args, kwargs):

        if not request.path_info.startswith('/manage/'):
            return

        project_id = kwargs.get('project_id')

        project_object = models.Project.objects.filter(creator=request.tracer.user, id=project_id).first()
        if project_object:

            request.tracer.project = project_object
            return

        project_user_object = models.ProjectUser.objects.filter(user=request.tracer.user, project_id=project_id).first()
        if project_user_object:

            request.tracer.project = project_user_object.project
            return

        return redirect('project_list')

3.5 Session配置文件补充及存储

1.数据库存储

Django默认支持Session,并且默认是将Session数据存储在数据库中,即:django_session 表中。

a. 配置 settings.py

SESSION_ENGINE = 'django.contrib.sessions.backends.db'

SESSION_COOKIE_NAME = "sessionid"
SESSION_COOKIE_PATH = "/"
SESSION_COOKIE_DOMAIN = None
SESSION_COOKIE_SECURE = False
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_AGE = 1209600
SESSION_EXPIRE_AT_BROWSER_CLOSE = False
SESSION_SAVE_EVERY_REQUEST = False

b. 使用

    def index(request):

        request.session['k1']
        request.session.get('k1',None)
        request.session['k1'] = 123
        request.session.setdefault('k1',123)
        del request.session['k1']

        request.session.keys()
        request.session.values()
        request.session.items()
        request.session.iterkeys()
        request.session.itervalues()
        request.session.iteritems()

        request.session.session_key

        request.session.clear_expired()

        request.session.exists("session_key")

        request.session.delete("session_key")

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

2.缓存Session

  • 缓存,存储在另一台(缓存服务器)机器内存中的数据。一般结合 redis使用
a. 配置 settings.py

    SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
    SESSION_CACHE_ALIAS = 'default'

    SESSION_COOKIE_NAME = "sessionid"
    SESSION_COOKIE_PATH = "/"
    SESSION_COOKIE_DOMAIN = None
    SESSION_COOKIE_SECURE = False
    SESSION_COOKIE_HTTPONLY = True
    SESSION_COOKIE_AGE = 1209600
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False
    SESSION_SAVE_EVERY_REQUEST = False

b. 使用
    同上

3.其他

文件Session
缓存+数据库Session
加密cookie Session
以上方式请点击参考文献进行观看。

4.装饰器的补充

def warper(f):
    def inner(*args,**kwargs):
        print('我是执行前的语句')
        ret=f()
        print('我是执行后的语句')
        return ret
    return inner

@warper
def tes1():
    print('***********')
    return '我是原函数的返回结果'
print(tes1())

Django的Session和cookie

5.知识梳理

Django的Session和cookie

; 继续努力,终成大器!

Original: https://blog.csdn.net/m0_61970162/article/details/122320568
Author: 紫青宝剑
Title: Django的Session和cookie

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/736567/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球