Django中和时区相关的安全问题详解

在开发国际化网站的时候,难免会与时区打交道,通用CMS更是如此,毕竟其潜在用户可能是来自于全球各地的。Django在时区这个问题上下了不少功夫,但是很多资深的开发者都有可能尚未完全屡清楚Django中各种时间的实际意义和使用方法,导致写出错误的代码;作为安全研究人员,时区问题也可能和一些安全问题挂钩,比如优惠券的过期时间、订单的下单与取消时间等,如果没有考虑时区问题,有可能将导致一些逻辑漏洞。本文就从多个常用模块开始,了解一下Django中的时区究竟是怎么回事,以及在时间的比较中可能出现的一些逻辑错误。
摘要由CSDN通过智能技术生成

在开发国际化网站的时候,难免会与时区打交道,通用CMS更是如此,毕竟其潜在用户可能是来自于全球各地的。Django在时区这个问题上下了不少功夫,但是很多资深的开发者都有可能尚未完全屡清楚Django中各种时间的实际意义和使用方法,导致写出错误的代码;作为安全研究人员,时区问题也可能和一些安全问题挂钩,比如优惠券的过期时间、订单的下单与取消时间等,如果没有考虑时区问题,有可能将导致一些逻辑漏洞。

本文就从多个常用模块开始,了解一下Django中的时区究竟是怎么回事,以及在时间的比较中可能出现的一些逻辑错误。

从“两种时间”说起

我们都知道,在Python中表示“时间”的对象是 datetime.datetime

其实在Python中,这个对象被分成了两个类型:

  • aware datetime
  • naive datetime

他们的区别是:如果 datetime 对象的 tzinfo 属性有设置时区值,则这个对象是一个aware
datime;否则它是一个naive datetime。

举个例子,我们平时在编写Python脚本的时候,使用下面这行代码获取当前时间:


    from datetime import datetime
    t = datetime.now()

此时,t是一个naive datetime,因为我们没有给他设置时区:

image-20201011010557126.png

naive
的中文意思大家应该都很熟悉,这里的大概意思就是“simple”,这是一个很简单、原始的时间对象。实际上就是指,计算机不知道这个时间,他的时区究竟是什么,它可能代表着北京时间,也可能是UTC时间,因为我们没有指定时区,我们无法“假设”其是计算机系统所在的时区,也无法“假设”其是UTC时区。也就是说,计算机拿到了一个naive
datetime,是无法准确地定位到某一个时间点的,也无法直接转换成一个unix时间戳。

那么相对的,aware
datetime就是计算机能准确知道其时区的时间对象,他是一个准确的时间点,就落在时间轴上的某个地方,不管从哪个时区看,这个点都是绝对固定的。所以,我们可以将一个aware
datetime转换成unix时间戳。

有的同学可能比较好奇,你说naive datetime无法转换成时间戳,那么为什么这个对象有一个 timestamp() 方法呢:

image-20201011012655581.png

原因我们查文档可以得出结论,如果对象是naive datetime,则会以当前系统本地时区为准。

Django的时区配置

回到Django。由于Django是一个国际化框架,时区相关处理自然是其必不可少的组成部分。Django的配置项中,有下面两个选项与时区相关:

  • USE_TZ
  • TIME_ZONE

USE_TZ 用来指定整个项目是否 使用时区TIME_ZONE 是默认时区的值。

如果 USE_TZ 的值设置为False,那么Django项目中所有时间都使用naive
datetime(除非有明确指定时区的情况)。也就是说,网站内存储和使用的时间全部是 TIME_ZONE 的值所指定的时区。

这样做有一些弊端:

  • 数据库中保存的是naive datetime,导致在跨区域迁移数据的时候,可能无法准确定位到某个时间点
  • 国际化企业可能面向不同国家有不同的网站,但后台数据库相同,此时究竟使用哪个时区保存和展示时间,将引起混乱
  • 即使是同一个网站的用户,他们可能来自于全球各地,查看到的时间却是统一的服务器时间,对于高交互式的应用十分不友好
  • 即使网站面向的用户仅来自于某一个地区,也会涉及到“夏时令”(Daylight Saving Time)相关的问题,每年可能将会导致两次时间误差

默认情况下,用 django-admin 生成的项目,其设置中 USE_TZ
等于True,这也是Django官方建议的配置。此时,在网站内部存储与使用的是UTC时间,而与用户交互时使用 TIME_ZONE 或手工的时区。

我们后文中也以Django的默认配置 USE_TZ=True 为前提条件,否则也没有讨论的必要了。

Django的时间函数

Django的包 django.utils.timezone 中有下面几个常用的时间相关函数:

  • now(),返回当前的UTC时间
  • localtime(),返回当前的本地时间(默认是TIME_ZONE配置指定的时区时间)
  • is_aw
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值