Django实践-05Cookie和Session

这篇具有很好参考价值的文章主要介绍了Django实践-05Cookie和Session。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


Django实践-05Cookie和Session

Django实践-05Cookie和Session

官网:https://www.djangoproject.com/
博客:https://www.liujiangblog.com/
本博客内容参考git:https://gitcode.net/mirrors/jackfrued/Python-100-Days 一些细节问题,大家可以查看git连接。本文主要的改变为把代码升级为django4.1版本。

Django静态文件问题备注:
参考:
Django测试开发-20-settings.py中templates配置,使得APP下的模板以及根目录下的模板均可生效
解决django 多个APP时 static文件的问题

django配置app中的静态文件步骤
Django多APP加载静态文件

django.short包参考:https://docs.djangoproject.com/en/4.1/topics/http/shortcuts/

Django实践-05Cookie和Session

我们继续来完成上一章节中的项目,实现“用户登录”的功能,并限制只有登录的用户才能投票。

用户登录的准备工作

1. 创建用户模型。

之前我们讲解过如果通过Django的ORM实现从二维表到模型的转换(反向工程),这次我们尝试把模型变成二维表(正向工程)。

class User(models.Model):
    """用户"""
    no = models.AutoField(primary_key=True, verbose_name='编号')
    username = models.CharField(max_length=20, unique=True, verbose_name='用户名')
    password = models.CharField(max_length=32, verbose_name='密码')
    tel = models.CharField(max_length=20, verbose_name='手机号')
    reg_date = models.DateTimeField(auto_now_add=True, verbose_name='注册时间')
    last_visit = models.DateTimeField(null=True, verbose_name='最后登录时间')

    class Meta:
        db_table = 'tb_user'
        verbose_name = '用户'
        verbose_name_plural = '用户'
2. 正向工程生成数据库表

使用下面的命令生成迁移文件并执行迁移,将User模型直接变成关系型数据库中的二维表tb_user。

python manage.py makemigrations polls

输出为:

E:\vscode\vip3-django\djangoproject>python manage.py makemigrations polls
Migrations for ‘polls’:
polls\migrations\0002_user.py
- Create model User

python manage.py migrate polls

输出为:

E:\vscode\vip3-django\djangoproject>python manage.py migrate polls
Operations to perform:
Apply all migrations: polls
Running migrations:
Applying polls.0002_user… OK

3.写utils.py文件,密码转md5

我们在应用下增加一个名为utils.py的模块用来保存需要使用的工具函数。Python标准库中的hashlib模块封装了常用的哈希算法,包括:MD5、SHA1、SHA256等。下面是使用hashlib中的md5类将字符串处理成MD5摘要的函数如下所示。

import hashlib

def gen_md5_digest(content):
    return hashlib.md5(content.encode()).hexdigest()

if __name__=="__main__":
    print("admin123456-->{}".format(gen_md5_digest("admin123456")))
    # admin123456-->a66abb5684c45962d887564f08346e8d
4.给数据表tb_user中插入测试数据

MD5消息摘要算法是一种被广泛使用的密码哈希函数(散列函数),可以产生出一个128位(比特)的哈希值(散列值),用于确保信息传输完整一致。在使用哈希值时,通常会将哈希值表示为16进制字符串,因此128位的MD5摘要通常表示为32个十六进制符号。

insert into `tb_user`
    (`username`, `password`, `tel`, `reg_date`)
values
    ('user1', 'a66abb5684c45962d887564f08346e8d', '13122334455', now()),
    ('user2', 'a66abb5684c45962d887564f08346e8d', '13890006789', now());

说明:上面创建的两个用户user1和user2密码是admin123456。

5.编写用户登录的视图函数和模板页。

在polls/views.py添加渲染登录页面的视图函数:

from django.http import HttpRequest, HttpResponse


def login(request: HttpRequest) -> HttpResponse:
    hint = ''
    return render(request, '/login.html', {'hint': hint})
6.编写urls.py。

在urls.py文件中添加路由

    path('login/', polls_views.login),# 登录
    path('logout/', polls_views.logout),# 注销
    path('captcha/', polls_views.get_captcha),# 验证码
    path('register/', polls_views.register),# 注册
6.增加login.html模板页:

CSRF的作用,参考
本博客内容参考git:https://gitcode.net/mirrors/jackfrued/Python-100-Days
在templates目录下创建login.html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户登录</title>
    <style>
        #container {
            width: 520px;
            margin: 10px auto;
        }
        .input {
            margin: 20px 0;
            width: 460px;
            height: 40px;
        }
        .input>label {
            display: inline-block;
            width: 140px;
            text-align: right;
        }
        .input>img {
            width: 150px;
            vertical-align: middle;
        }
        input[name=captcha] {
            vertical-align: middle;
        }
        form+div {
            margin-top: 20px;
        }
        form+div>a {
            text-decoration: none;
            color: darkcyan;
            font-size: 1.2em;
        }
        .button {
            width: 500px;
            text-align: center;
            margin-top: 20px;
        }
        .hint {
            color: red;
            font-size: 12px;
        }
    </style>
</head>
<body>
    <div id="container">
        <h1>用户登录</h1>
        <hr>
        <p class="hint">{{ hint }}</p>
        <form action="/login/" method="post">
            {% csrf_token %}
            <fieldset>
                <legend>用户信息</legend>
                <div class="input">
                    <label>用户名:</label>
                    <input type="text" name="username">
                </div>
                <div class="input">
                    <label>密码:</label>
                    <input type="password" name="password">
                </div>
                <div class="input">
                    <label>验证码:</label>
                    <input type="text" name="captcha">
                    <img id="code" src="/captcha/" alt="" width="150" height="40">
                </div>
            </fieldset>
            <div class="button">
                <input type="submit" value="登录">
                <input type="reset" value="重置">
            </div>
        </form>
        <div>
            <a href="/">返回首页</a>
            <a href="/register/">注册新用户</a>
        </div>
    </div>
</body>
</html>

实现用户跟踪

在服务器端,创建一个session对象,通过这个对象就可以把用户相关的信息都保存起来。我们可以给每个session对象分配一个全局唯一的标识符来识别session对象,我们姑且称之为sessionid,每次客户端发起请求时,只要携带上这个sessionid,就有办法找到与之对应的session对象,从而实现在两次请求之间记住该用户的信息,也就是我们之前说的用户跟踪。

要让客户端记住并在每次请求时带上sessionid又有以下几种做法:

  1. URL重写。所谓URL重写就是在URL中携带sessionid,例如:http://www.example.com/index.html?sessionid=123456,服务器通过获取sessionid参数的值来取到与之对应的session对象。
  2. 隐藏域(隐式表单域)。在提交表单的时候,可以通过在表单中设置隐藏域向服务器发送额外的数据。例如:<input type=“hidden” name=“sessionid” value=“123456”>。
  3. 本地存储。现在的浏览器都支持多种本地存储方案,包括:cookie、localStorage、sessionStorage、IndexedDB等。在这些方案中,cookie是历史最为悠久也是被诟病得最多的一种方案,也是我们接下来首先为大家讲解的一种方案。

Django框架对session的支持

在创建Django项目时,默认的配置文件settings.py文件中已经激活了一个名为SessionMiddleware的中间件,因为这个中间件的存在,我们可以直接通过请求对象的session属性来操作会话对象。与此同时,SessionMiddleware中间件还封装了对cookie的操作,在cookie中保存了sessionid。

在默认情况下,Django将session的数据序列化后保存在关系型数据库中,在后面的章节中将session保存到缓存服务中以提升系统的性能。

实现用户登录验证

生成验证码随机数

首先,我们在刚才的polls/utils.py文件中编写生成随机验证码的函数gen_random_code,内容如下所示。

import random

ALL_CHARS = '23456789abcdefghjklmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'


def gen_random_code(length=4):
    return ''.join(random.choices(ALL_CHARS, k=length))
添加字体与验证码图片类Captcha

创建polls/fonts目录,放置arialbd.ttf

在polls目录下编写生成验证码图片的类Captcha。

"""
图片验证码
"""
import os
import random
from io import BytesIO

from PIL import Image
from PIL import ImageFilter
from PIL.ImageDraw import Draw
from PIL.ImageFont import truetype


class Bezier:
    """贝塞尔曲线"""

    def __init__(self):
        self.tsequence = tuple([t / 20.0 for t in range(21)])
        self.beziers = {}

    def make_bezier(self, n):
        """绘制贝塞尔曲线"""
        try:
            return self.beziers[n]
        except KeyError:
            combinations = pascal_row(n - 1)
            result = []
            for t in self.tsequence:
                tpowers = (t ** i for i in range(n))
                upowers = ((1 - t) ** i for i in range(n - 1, -1, -1))
                coefs = [c * a * b for c, a, b in zip(combinations,
                                                      tpowers, upowers)]
                result.append(coefs)
            self.beziers[n] = result
            return result


class Captcha:
    """验证码"""

    def __init__(self, width, height, fonts=None, color=None):
        self._image = None
        self._fonts = fonts if fonts else \
            [os.path.join(os.path.dirname(__file__), 'fonts', font)
             for font in ['arialbd.ttf']]# arialbd.ttf
             #for font in ['Arial.ttf', 'Georgia.ttf', 'Action.ttf']]# arialbd.ttf
        self._color = color if color else random_color(0, 200, random.randint(220, 255))
        self._width, self._height = width, height

    @classmethod
    def instance(cls, width=200, height=75):
        """用于获取Captcha对象的类方法"""
        prop_name = f'_instance_{width}_{height}'
        if not hasattr(cls, prop_name):
            setattr(cls, prop_name, cls(width, height))
        return getattr(cls, prop_name)

    def _background(self):
        """绘制背景"""
        Draw(self._image).rectangle([(0, 0), self._image.size],
                                    fill=random_color(230, 255))

    def _smooth(self):
        """平滑图像"""
        return self._image.filter(ImageFilter.SMOOTH)

    def _curve(self, width=4, number=6, color=None):
        """绘制曲线"""
        dx, height = self._image.size
        dx /= number
        path = [(dx * i, random.randint(0, height))
                for i in range(1, number)]
        bcoefs = Bezier().make_bezier(number - 1)
        points = []
        for coefs in bcoefs:
            points.append(tuple(sum([coef * p for coef, p in zip(coefs, ps)])
                                for ps in zip(*path)))
        Draw(self._image).line(points, fill=color if color else self._color, width=width)

    def _noise(self, number=50, level=2, color=None):
        """绘制扰码"""
        width, height = self._image.size
        dx, dy = width / 10, height / 10
        width, height = width - dx, height - dy
        draw = Draw(self._image)
        for i in range(number):
            x = int(random.uniform(dx, width))
            y = int(random.uniform(dy, height))
            draw.line(((x, y), (x + level, y)),
                      fill=color if color else self._color, width=level)

    def _text(self, captcha_text, fonts, font_sizes=None, drawings=None, squeeze_factor=0.75, color=None):
        """绘制文本"""
        color = color if color else self._color
        fonts = tuple([truetype(name, size)
                       for name in fonts
                       for size in font_sizes or (65, 70, 75)])
        draw = Draw(self._image)
        char_images = []
        for c in captcha_text:
            font = random.choice(fonts)
            c_width, c_height = draw.textsize(c, font=font)
            char_image = Image.new('RGB', (c_width, c_height), (0, 0, 0))
            char_draw = Draw(char_image)
            char_draw.text((0, 0), c, font=font, fill=color)
            char_image = char_image.crop(char_image.getbbox())
            for drawing in drawings:
                d = getattr(self, drawing)
                char_image = d(char_image)
            char_images.append(char_image)
        width, height = self._image.size
        offset = int((width - sum(int(i.size[0] * squeeze_factor)
                                  for i in char_images[:-1]) -
                      char_images[-1].size[0]) / 2)
        for char_image in char_images:
            c_width, c_height = char_image.size
            mask = char_image.convert('L').point(lambda i: i * 1.97)
            self._image.paste(char_image,
                              (offset, int((height - c_height) / 2)),
                              mask)
            offset += int(c_width * squeeze_factor)

    @staticmethod
    def _warp(image, dx_factor=0.3, dy_factor=0.3):
        """图像扭曲"""
        width, height = image.size
        dx = width * dx_factor
        dy = height * dy_factor
        x1 = int(random.uniform(-dx, dx))
        y1 = int(random.uniform(-dy, dy))
        x2 = int(random.uniform(-dx, dx))
        y2 = int(random.uniform(-dy, dy))
        warp_image = Image.new(
            'RGB',
            (width + abs(x1) + abs(x2), height + abs(y1) + abs(y2)))
        warp_image.paste(image, (abs(x1), abs(y1)))
        width2, height2 = warp_image.size
        return warp_image.transform(
            (width, height),
            Image.QUAD,
            (x1, y1, -x1, height2 - y2, width2 + x2, height2 + y2, width2 - x2, -y1))

    @staticmethod
    def _offset(image, dx_factor=0.1, dy_factor=0.2):
        """图像偏移"""
        width, height = image.size
        dx = int(random.random() * width * dx_factor)
        dy = int(random.random() * height * dy_factor)
        offset_image = Image.new('RGB', (width + dx, height + dy))
        offset_image.paste(image, (dx, dy))
        return offset_image

    @staticmethod
    def _rotate(image, angle=25):
        """图像旋转"""
        return image.rotate(random.uniform(-angle, angle),
                            Image.BILINEAR, expand=1)

    def generate(self, captcha_text='', fmt='PNG'):
        """生成验证码(文字和图片)
        :param captcha_text: 验证码文字
        :param fmt: 生成的验证码图片格式
        :return: 验证码图片的二进制数据
        """
        self._image = Image.new('RGB', (self._width, self._height), (255, 255, 255))
        self._background()
        self._text(captcha_text, self._fonts,
                   drawings=['_warp', '_rotate', '_offset'])
        self._curve()
        self._noise()
        self._smooth()
        image_bytes = BytesIO()
        self._image.save(image_bytes, format=fmt)
        return image_bytes.getvalue()


def pascal_row(n=0):
    """生成毕达哥拉斯三角形(杨辉三角)"""
    result = [1]
    x, numerator = 1, n
    for denominator in range(1, n // 2 + 1):
        x *= numerator
        x /= denominator
        result.append(x)
        numerator -= 1
    if n & 1 == 0:
        result.extend(reversed(result[:-1]))
    else:
        result.extend(reversed(result))
    return result


def random_color(start=0, end=255, opacity=255):
    """获得随机颜色"""
    red = random.randint(start, end)
    green = random.randint(start, end)
    blue = random.randint(start, end)
    if opacity is None:
        return red, green, blue
    return red, green, blue, opacity

说明:上面的代码中用到了三个字体文件,字体文件位于polls/fonts目录下,大家可以自行添加字体文件,但是需要注意字体文件的文件名跟上面代码的第45行保持一致。

修改polls/views.py文件处理验证码请求与修改登录请求

接下来,我们先完成提供验证码的视图函数。

from polls.Captcha import Captcha
from polls.utils import gen_random_code



def get_captcha(request: HttpRequest) -> HttpResponse:
    """验证码"""
    captcha_text = gen_random_code()
    request.session['captcha'] = captcha_text
    image_data = Captcha.instance().generate(captcha_text)
    return HttpResponse(image_data, content_type='image/png')

注意上面代码中的第4行,我们将随机生成的验证码字符串保存到session中,稍后用户登录时,我们要将保存在session中的验证码字符串和用户输入的验证码字符串进行比对,如果用户输入了正确的验证码才能够执行后续的登录流程,代码如下所示。

from polls.Captcha import Captcha
from polls.utils import gen_md5_digest, gen_random_code

from polls.models import User


def login(request: HttpRequest) -> HttpResponse:
    hint = ''
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        if username and password:
            password = gen_md5_digest(password)
            user = User.objects.filter(username=username, password=password).first()
            if user:
                request.session['userid'] = user.no
                request.session['username'] = user.username
                return redirect('/')
            else:
                hint = '用户名或密码错误'
        else:
            hint = '请输入有效的用户名和密码'
    return render(request, 'login.html', {'hint': hint})

说明:上面的代码没有对用户名和密码没有进行验证,实际项目中建议使用正则表达式验证用户输入信息,否则有可能将无效的数据交给数据库进行处理或者造成其他安全方面的隐患。

上面的代码中,我们设定了登录成功后会在session中保存用户的编号(userid)和用户名(username),页面会重定向到首页。

修改polls/views.py文件,logout函数

如果用户没有登录,页面会显示登录和注册的超链接;而用户登录成功后,页面上会显示用户名和注销的链接,注销链接对应的视图函数如下所示,URL的映射与之前讲过的类似,不再赘述。

def logout(request):
    """注销"""
    request.session.flush()
    return redirect('/')

上面的代码通过session对象flush方法来销毁session,一方面清除了服务器上session对象保存的用户数据,一方面将保存在浏览器cookie中的sessionid删除掉,稍后我们会对如何读写cookie的操作加以说明。

我们可以通过项目使用的数据库中名为django_session 的表来找到所有的session,该表的结构如下所示:
Django实践-05Cookie和Session

其中,第1列就是浏览器cookie中保存的sessionid;第2列是经过BASE64编码后的session中的数据。

修改polls/views.py文件praise_or_criticize函数,限制只有登录的用户才能投票

接下来,我们就可以限制只有登录用户才能为老师投票,修改后的praise_or_criticize函数如下所示,我们通过从request.session中获取userid来判定用户是否登录。

def praise_or_criticize(request: HttpRequest) -> HttpResponse:
    if request.session.get('userid'):
        try:
            tno = int(request.GET.get('tno'))
            teacher = Teacher.objects.get(no=tno)
            if request.path.startswith('/praise/'):
                teacher.good_count += 1
                count = teacher.good_count
            else:
                teacher.bad_count += 1
                count = teacher.bad_count
            teacher.save()
            data = {'code': 20000, 'mesg': '投票成功', 'count': count}
        except (ValueError, Teacher.DoesNotExist):
            data = {'code': 20001, 'mesg': '投票失败'}
    else:
        data = {'code': 20002, 'mesg': '请先登录'}
    return JsonResponse(data)
修改teachers.html,如果没有登录,跳转到登录页

当然,在修改了视图函数后,teachers.html也需要进行调整,用户如果没有登录,就将用户引导至登录页,登录成功再返回到投票页,此处不再赘述。

window.location.href='http://127.0.0.1:8000/login/';

实现用户注册

修改polls/views.py添加register函数
def register(request: HttpRequest) -> HttpResponse:
    from datetime import datetime
    reg_date = datetime.now()

    hint = ''
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        password = gen_md5_digest(password)
        tel = request.POST.get('tel')
        user = User.objects.filter(username=username).first()
        if user:
            hint = '用户名已存在'
            return render(request, 'register.html', {'hint': hint})

        print(reg_date,"<--------reg_date")
        user = User(username=username,password=password,tel=tel,reg_date=reg_date,)
        user.save()

        
        user = User.objects.filter(username=username).first()
        if user:
            hint="用户 {} 注册成功".format(username)
            return redirect('/')
        else:
            hint = '请重新注册'
            return render(request, 'register.html', {'hint': hint})

    return render(request, 'register.html', {'hint': hint})
修改urls.py文件,添加注册路由
path('register/', polls_views.register),# 注册 本部分新增 前面如果已经添加九不要重复添加
创建templates/register.html

templates/register.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户注册</title>
    <style>
        #container {
            width: 520px;
            margin: 10px auto;
        }
        .input {
            margin: 20px 0;
            width: 460px;
            height: 40px;
        }
        .input>label {
            display: inline-block;
            width: 140px;
            text-align: right;
        }
        .input>img {
            width: 150px;
            vertical-align: middle;
        }
        input[name=captcha] {
            vertical-align: middle;
        }
        form+div {
            margin-top: 20px;
        }
        form+div>a {
            text-decoration: none;
            color: darkcyan;
            font-size: 1.2em;
        }
        .button {
            width: 500px;
            text-align: center;
            margin-top: 20px;
        }
        .hint {
            color: red;
            font-size: 12px;
        }
    </style>
</head>
<body>
    <div id="container">
        <h1>用户注册</h1>
        <hr>
        <p class="hint">{{ hint }}</p>
        <form action="/register/" method="post">
            {% csrf_token %}
            <fieldset>
                <legend>用户信息</legend>
                <div class="input">
                    <label>用户名:</label>
                    <input type="text" name="username">
                </div>
                <div class="input">
                    <label>密码:</label>
                    <input type="password" name="password">
                </div>
                <div class="input">
                    <label>手机:</label>
                    <input type="text" name="tel">
                </div>
                <div class="input">
                    <label>验证码:</label>
                    <input type="text" name="captcha">
                    <img id="code" src="/captcha/" alt="" width="150" height="40">
                </div>
            </fieldset>
            <div class="button">
                <input type="submit" value="注册">
                <input type="reset" value="重置">
            </div>
        </form>
        <div>
            <a href="/">返回首页</a>
            <a href="/login/">登录</a>
        </div>
    </div>
</body>
</html>

总结

本文主要是Django系列博客。本文是Django静态资源与Ajax请求示例。
1.创建静态资源目录
2.配置settings.py文件
3.修改urls.py文件
4.修改views.py文件
5.修改teachers.html文件文章来源地址https://www.toymoban.com/news/detail-416484.html

到了这里,关于Django实践-05Cookie和Session的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Django基础入门⑬:Cookie和Session详讲和Django HTML表单实战讲解

    🏘️🏘️个人简介:以山河作礼。 🎖️🎖️: Python领域新星创作者,CSDN实力新星认证,阿里云社区专家博主,CSDN内容合伙人 🎁🎁:Web全栈开发专栏:《Web全栈开发》免费专栏,欢迎阅读! 🎁🎁: 文章末尾扫描二维码可以加入粉丝交流群,不定期免费送书。 📑📑 在 Dja

    2024年02月13日
    浏览(42)
  • 跨越HTTP无状态边界:Cookie与Session在Django中的实战应用

    本文深入探索了Django中的Cookie和Session,解析了如何应对HTTP协议的无状态性问题,说明其基础概念,分析工作原理,并讨论何时应选择使用Cookie或Session。文章进阶部分,提出高效管理Cookie和Session,以及如何利用它们进行用户身份验证。 HTTP,即超文本传输协议,是一种应用层

    2024年02月13日
    浏览(43)
  • Django模板,Django中间件,ORM操作(pymysql + SQL语句),连接池,session和cookie, 缓存

    今日概要: 模板 中间件 ORM操作(pymysql + SQL语句) session和cookie 缓存(很多种方式) 请求周期 路由系统 最基本路由关系 动态路由(含正则) 路由分发不同的app中 + include + 本质 + name + namespace 视图 类和函数(FBV和CBV) 参数 request 请求数据 自定义数据 响应 其他知识 虚拟环

    2024年02月04日
    浏览(42)
  • Cookie和Session

    HTTP协议自身是属于无状态的协议,意思就是默认情况下HTTP协议的客户端和服务器的上一次通信和下一次通信之间是没有关系的,在实际开发中我们需要知道请求之间的关联关系,例如我们登陆过一个网站,当再次登陆该网站时,服务器就知道已经登陆过该网站了 回顾关于cookie的几

    2024年02月01日
    浏览(38)
  • session和cookie详解

    访问网站后在本地存储的相关网站信息 ,是服务器在本地机器上存储的文本,并随着每一个请求发送到同一服务器上,以便某些网站为了辨别用户身份,由用户客户端计算机暂时或永久保存的信息,是客户端保存状态的一种方式。 1.web程序是使用HTTP协议传输的,而HTTP协议是

    2024年02月05日
    浏览(45)
  • session和cookie

    三种域对象 这三个域对象的大小关系: request session application, 尽量使用小的域 request 请求域(请求级别的), 对应的类名:HttpServletRequest session会话域(用户级别的), 对应的类名:HttpSession application应用域(项目级别的,所有用户共享的)对应的类名:ServletContext 三个域对象都

    2024年02月07日
    浏览(44)
  • 【Cookie和Session】

    🎉🎉🎉 点进来你就是我的人了 博主主页: 🙈🙈🙈 戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔 🤺🤺🤺 目录 一、Cookie和Session(面试常考)  1. Cookie 2. Session  3. Cookie和Session是如何一起工作的?  4. Cookie和Session的过期校验 5. Cookie和Session的关联和区别 二、

    2024年02月07日
    浏览(35)
  • 认识Cookie和Session

    一个网站,怎么证明你来过? 客户端          服务端 1.服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了;cookie 2.服务器登记你来过了,下次你来的时候我来匹配你;session 现在我们来了解cookie和session cookie是什么? cookie(cookie)是指网站为了辨别用户身

    2024年02月03日
    浏览(58)
  • cookie+session和token

    总结说在前面: session:起源于服务端,保存在服务端(服务器或者数据库),通过cookie传递给用户,用户每一次发送HTTP请求的时候,通过验证cookie中的session-id来验证用户身份。 jwt(json web token):起源于服务端,保存在浏览器(cookie或者storage),和session一样,用户每一次发

    2024年02月19日
    浏览(43)
  • session、cookie、token的区别?

    今天就来理一理session、cookie、token这三者之间的关系! 我们都知道 HTTP 协议是无状态的,所谓的无状态就是客户端每次想要与服务端通信,都必须重新与服务端链接,意味着请求一次客户端和服务端就连接一次,下一次请求与上一次请求是没有关系的。 这种无状态的方式就

    2023年04月12日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包