前言
最近一段时间研究了Django中基于token的用户验证机制,在Django的文档中,只是简单的提到可以通过token自定义用户验证系统,于是在github上找到Django-tokenapi,将它在自己的项目上进行了安装与测试,同事详细读了它的代码。
Django-tokenapi中token的加密方式
代码分析
在token的生成中,可以有不同的构成方式,在Django-tokenapi中源码如下:
def _make_token_with_timestamp(self, user, timestamp):
# timestamp is number of days since 2001-1-1. Converted to
# base 36, this gives us a 3 digit string until about 2121
ts_b36 = int_to_base36(timestamp)
key_salt = "tokenapi.tokens.PasswordResetTokenGenerator"
value = (six.text_type(user.pk) + user.password + six.text_type(timestamp))
hash = salted_hmac(key_salt, value).hexdigest()[::2]
return "%s-%s" % (ts_b36, hash)
可以看出它在生成token的时候,用到了一些参数值,如用户pk、用户密码、时间戳等。其实在salted_hmac()
中还用到了settings.py
中的SECRET_KEY
,这个参数没有在参数列表中写出来:
user.pk
:用户pk
user.password
:用户密码
timestamp
:时间戳,在这里其实是某设定日期到当前日期的天数
SECRET_KEY
:它的值设定在settings.py
中,由于它在站点配置中设置,所以对其他人来说,生成的token值是不可预测的
key_salt
:它的值在有些地方被解释为硬编码,其实就是一段固定值,看了Django’s reset password mechanism这篇文章,我暂时将它理解为在token生成时对不同应用场景的描述,它会影响生成的token值(有待研究)
token结构
这里生成的token如4my-87c88b35dad48ff02a1b
,由三部分构成,4my
是将时间通过int_to_base36(timestamp)
编码(相当于转换为36进制)后的值,能够反解出来。-
仅仅是连接线,87c88b35dad48ff02a1b
就是通过前面的参数加密后得到的值。
jwt值得一看