django -- cookie和session (一)

简介: django -- cookie和session

前戏


我们在访问一些网站的时候,如果没有登录就会跳转到登录页面,如果是登录了,才会让我们访问,那服务器是怎么知道我们有没有登录呢?这就涉及到了Cookie,大家都知道HTTP的特点,无状态。也就是浏览器发送到服务器的每个请求都是没有关系的。这时候就要给服务器设置一个Cookie,下次浏览器请求的时候,携带这个Cookie,如果有携带,那服务器就认为是登录的,如果没有携带或错误,那浏览器就跳转到登录页面。

什么是Cookie呢?

Cookie是指一小段信息,它是服务器发送出来存储在浏览器上的一组组键值对,下次访问服务器时浏览器会自动携带这些键值对。Cookie的工作原理是由服务器产生内容,浏览器收到请求后保存在本地,当浏览器再次访问时,浏览器会自动带上Cookie,这样服务器就能通过Cookie判断当前用户是哪个了


Cookie初识


login.html

我们写三个视图函数,login,home和index

from django.shortcuts import render,redirect,HttpResponse
from appTest01 import models
# Create your views here.
def login(request):
    if request.method == 'POST':
        user = request.POST.get('username')
        password = request.POST.get('pwd')
        if models.Person.objects.filter(name=user, pwd= password):
            return redirect('/index/')
    return render(request,'login.html')
def index(request):
    return HttpResponse('index')
def home(request):
    return HttpResponse('home')

上面这样的写法,我们可以直接通过路径访问对应的页面,不需要登录,当然不符合我们的需求,那我们给加上Cookie

from django.shortcuts import render,redirect,HttpResponse
from appTest01 import models
# Create your views here.
def login(request):
    if request.method == 'POST':
        user = request.POST.get('username')
        password = request.POST.get('pwd')
        if models.Person.objects.filter(name=user, pwd= password):
            ret = redirect('/index/')
            ret.set_cookie('is_login','yes')
            return ret
    return render(request,'login.html')
def index(request):
    print(request.COOKIES,type(request.COOKIES))  查看cookie
    return HttpResponse('index')
def home(request):
    return HttpResponse('home')

我们使用set_cookie()来设置Cookie,然后我们输入账号密码去登录,查看cookie

我们可以使用 request.COOKIES来查看cookie,

request.COOKIES,type(request.COOKIES)

结果:

{'csrftoken': 'pB5vZxQOwWnvNyw13S0ImpbInxOpnIV0BsAcE31hCHLOP3EIMM8veLpxIlcRBYIg', 'is_login': 'yes'} <class 'dict'>

既然它是一个字典类型的,我们就可以拿到cookie,然后在进行一个判断,在来改写视图函数

from django.shortcuts import render,redirect,HttpResponse
from appTest01 import models
# Create your views here.
def login(request):
    if request.method == 'POST':
        user = request.POST.get('username')
        password = request.POST.get('pwd')
        if models.Person.objects.filter(name=user, pwd = password):
            ret = redirect('/index/')
            ret.set_cookie('is_login','yes')
            return ret
    return render(request,'login.html')
def index(request):
    if request.COOKIES.get('is_login') == 'yes':  # 获取我们设置的Cookie
        return HttpResponse('index')
    return redirect('/login/')
def home(request):
    if request.COOKIES.get('is_login') == 'yes':
        return HttpResponse('home')
    return redirect('/login/')

上面代码我们就实现了我们的需求,如果登录成功,可以访问index和home页面,如果没有登录,则返回login页面,那试想一下,以后我们的项目页面有几百个,难道要给每个页面都要写判断吗?这样肯定是不行的,我们可以用装饰器来实现这种需求,代码如下

from django.shortcuts import render, redirect, HttpResponse
from appTest01 import models
# Create your views here.
def login_cookie(f):
    def inner(request, *args, **kwargs):
        if request.COOKIES.get('is_login') == 'yes':  # 获取我们设置的Cookie,如果通过,执行被装饰的函数
            res = f(request, *args, **kwargs)
            return res
        return redirect('/login/')
    return inner
def login(request):
    if request.method == 'POST':
        user = request.POST.get('username')
        password = request.POST.get('pwd')
        if models.Person.objects.filter(name=user, pwd=password):
            ret = redirect('/index/')
            ret.set_cookie('is_login', 'yes')
            return ret
    return render(request, 'login.html')
@login_cookie
def index(request):
    return HttpResponse('index')
@login_cookie
def home(request):
    return HttpResponse('home')

但是这样又有个问题,如果我们没有登录访问home页面,它会跳转到登录页面,我们正确登录之后返回到了index页面,这肯定不是我们需要的效果,因为我们在login函数里已经写死了,登录成功之后返回的是index页面,我们来看下京东没登录时点击“我的京东”是怎样处理的

我们可以看到,京东在登录页面后面加了个参数,然后登录成功之后,直接跳转到后面的那个参数页面了,那我们在来修改我们的代码

from django.shortcuts import render, redirect, HttpResponse
from appTest01 import models
# Create your views here.
def login_cookie(f):
    def inner(request, *args, **kwargs):
        current_url = request.path_info  # 获取地址中?后面的参数
        print('current_url为:', current_url)
        if request.COOKIES.get('is_login') == 'yes':
            res = f(request, *args, **kwargs)
            return res
        return redirect('/login/?returnurl={}'.format(current_url))  # 拼接url路径
    return inner
def login(request):
    if request.method == 'POST':
        user = request.POST.get('username')
        password = request.POST.get('pwd')
        if models.Person.objects.filter(name=user, pwd=password):
            url_parameter = request.GET.get('returnurl')  # 获取当前路径里的returnurl参数
            ret = redirect(url_parameter)  # 返回到returnurl页面
            ret.set_cookie('is_login', 'yes')
            return ret
    return render(request, 'login.html')
@login_cookie
def index(request):
    return HttpResponse('index')
@login_cookie
def home(request):
    return HttpResponse('home')

结果:

如果你在未登录状态下访问home页面,current_url就为/home/
如果你在未登录状态下访问index页面,current_url就为/index/

那么问题又来了,如果我们直接访问login页面,登录成功则会报错,这是因为当前的 url_parameter 参数为空,只需要修改login函数里的东西就可以了

def login(request):
    if request.method == 'POST':
        user = request.POST.get('username')
        password = request.POST.get('pwd')
        if models.Person.objects.filter(name=user, pwd=password):
            url_parameter = request.GET.get('returnurl')  # 获取当前路径里的returnurl参数
            if url_parameter:  # 如果有值
                ret = redirect(url_parameter)  # 返回到returnurl页面
            else:  # 如果为空
                ret = redirect('/home/')
            ret.set_cookie('is_login', 'yes')
            return ret
    return render(request, 'login.html')


设置和获取Cookie


在上面的例子中,我们是使用 set_cookie()来进行设置Cookie,还有另一种方式

rep = HttpResponse(...)
rep = render(request, ...)
rep.set_cookie(key,value,...)
rep.set_signed_cookie(key,value,salt='加密盐',...)

获取Cookie就不能使用request.COOKIES[’key‘]或者request.COOKIES.get('key')的方法获取了,要使用如下的方法获取

request.get_signed_cookie('key', default=RAISE_ERROR, salt='', max_age=None)

get_signed_cookie方法的参数:

  • default: 默认值
  • salt: 加密盐
  • max_age: 后台控制过期时间


删除Cookie


删除Cookie使用delete_cookie('key')

def loginout(request):
    res = redirect('/login/')
    res.delete_cookie('is_login')  # 删除我们设置的is_login的cookie
    return res


Cookie的其他参数


  1. key,键
  2. value='' 值
  3. max_age=xx   超时时间,xx为一个int型的,单位为秒,如xx=60,则cookie的有效期为60秒
  4. path='/', Cookie生效的路径,/ 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问
  5. domain=None, Cookie生效的域名
  6. secure=False, https传输
  7. httponly=False 只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)

相关文章
|
14天前
|
存储 前端开发 Java
【SpringMVC】——Cookie和Session机制
获取URL中参数@PathVarible,上传文件@RequestPart,HttpServerlet(getCookies()方法,getAttribute方法,setAttribute方法,)HttpSession(getAttribute方法),@SessionAttribute
|
2月前
|
存储 安全 搜索推荐
理解Session和Cookie:Java Web开发中的用户状态管理
理解Session和Cookie:Java Web开发中的用户状态管理
86 4
|
2月前
|
存储 缓存 网络协议
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点,GET、POST的区别,Cookie与Session
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点、状态码、报文格式,GET、POST的区别,DNS的解析过程、数字证书、Cookie与Session,对称加密和非对称加密
|
3月前
|
缓存 Java Spring
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
文章比较了在Servlet和Spring Boot中获取Cookie、Session和Header的方法,并提供了相应的代码实例,展示了两种方式在实际应用中的异同。
231 3
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
|
3月前
|
存储 安全 数据安全/隐私保护
Cookie 和 Session 的区别及使用 Session 进行身份验证的方法
【10月更文挑战第12天】总之,Cookie 和 Session 各有特点,在不同的场景中发挥着不同的作用。使用 Session 进行身份验证是常见的做法,通过合理的设计和管理,可以确保用户身份的安全和可靠验证。
49 1
|
4月前
|
存储 缓存 数据处理
php学习笔记-php会话控制,cookie,session的使用,cookie自动登录和session 图书上传信息添加和修改例子-day07
本文介绍了PHP会话控制及Web常用的预定义变量,包括`$_REQUEST`、`$_SERVER`、`$_COOKIE`和`$_SESSION`的用法和示例。涵盖了cookie的创建、使用、删除以及session的工作原理和使用,并通过图书上传的例子演示了session在实际应用中的使用。
php学习笔记-php会话控制,cookie,session的使用,cookie自动登录和session 图书上传信息添加和修改例子-day07
|
4月前
|
存储 前端开发 Java
JavaWeb基础7——会话技术Cookie&Session
会话技术、Cookie的发送和获取、存活时间、Session钝化与活化、销毁、用户登录注册“记住我”和“验证码”案例
JavaWeb基础7——会话技术Cookie&Session
|
5月前
|
存储 缓存 中间件
Django 框架中 Session 的用法
【8月更文挑战第30天】
51 6
|
4月前
|
存储 安全 NoSQL
Cookie、Session、Token 解析
Cookie、Session、Token 解析
86 0
|
5月前
|
存储 JavaScript 前端开发
Cookie 反制策略详解:Cookie加解密原理、Cookie和Session机制、Cookie hook、acw_sc__v2、jsl Cookie调试、重定向Cookie
Cookie 反制策略详解:Cookie加解密原理、Cookie和Session机制、Cookie hook、acw_sc__v2、jsl Cookie调试、重定向Cookie
334 1