[英]How to generate a unique auth token in python?
我正在尝试为我的 android 应用程序在烧瓶中编写一个基于令牌的身份验证。 为此,我需要一个唯一的令牌,我可以使用它来验证用户。
它的危险库提供了一个 JSONWebSignatureSerializer 函数,我可以使用它来创建 JWT 令牌。 所以我的第一个问题是,将 JWT 用于基于移动的身份验证是否安全?
其次,我对 django rest 框架如何生成其令牌进行了一些研究。
def generate_key(self):
return binascii.hexlify(os.urandom(20)).decode()
这个令牌是唯一的还是只是一个随机的? 我应该使用哪一个进行基于移动的身份验证?
在 python 中为移动应用程序生成唯一令牌的基本方法是什么?
您可以像提到的那样使用内置uuid
模块。 3.6 中发布的新secrets
模块也能够创建独特的令牌。
from uuid import uuid4
rand_token = uuid4()
下面的函数每次被调用时都会创建一个唯一的令牌。 os.urandom
方法以字符串形式返回 20 个随机字节,而binascii.hexlify
方法将这 20 个字节中的每一个都转换binascii.hexlify
字节的 2 位十六进制表示。 这就是为什么返回值是两倍长的原因。
如果您想使用这种方法并且需要令牌具有特定长度,请使用所需长度的一半作为os.urandom
方法的参数。
def generate_key(self):
return binascii.hexlify(os.urandom(20)).decode()
好吧,这已经过时了,但我还是要插嘴。 你需要决定:你想要独特的还是随机的? 选一个。
如果您想要唯一,请使用 UUID。 UUID 的全部目的是确保您生成独特的东西。 UUID 代表通用唯一 ID。
如果你想要一些随机的东西,使用os.urandom
。 真正随机的结果不能局限于唯一性约束! 那会使它们不随机。 事实上,它会使它们成为 UUID。
现在,对于您的问题,您需要一个身份验证令牌。 这意味着您出于安全目的使用它。 UUID 是错误的解决方案,而生成安全号码是正确的解决方案。 生成随机数而不是 UUID 时会发生冲突吗? 是的。 但除非你有无数用户,否则这是不可能的。 您会想对此进行数学计算,但我的建议是:当您打算使用随机时,不要使用 UUID。
哎呀。
我写了一个小辅助函数,用于在 django 模型中生成一个唯一的标记。 您可以从模型的save()
方法调用它。 它使用定义的函数生成候选标记,在数据库中的现有行中搜索该候选标记。 如果找到,则重试,否则返回候选字符串。 请注意,这里有一个小的竞争条件,但不太可能发生在具有足够大范围输出的令牌函数中。
def generate_unique_token(Model,
token_field="token",
token_function=lambda: uuid.uuid4().hex[:8]):
"""
Generates random tokens until a unique one is found
:param Model: a Model class that should be searched
:param token_field: a string with the name of the token field to search in the model_class
:param token_function: a callable that returns a candidate value
:return: the unique candidate token
"""
unique_token_found = False
while not unique_token_found:
token = token_function()
# This weird looking construction is a way to pass a value to a field with a dynamic name
if Model.objects.filter(**{token_field:token}).count() is 0:
unique_token_found = True
return token
然后,您只需调用即可找到唯一的令牌
token = generate_unique_token(MyModelInstance, "token_field_name")
它甚至支持使用其他生成令牌的方法。 例如,如果你想使用完整的 uuid,你可以简单地像这样调用它:
token = generate_unique_token(MyModel, "token_field_name", lambda: uuid.uuid4().hex)
一个可能的解决方案是 AES 加密令牌过期的时间 + 用户名,这使得发现过期令牌变得相当容易,并且不需要额外的令牌数据库空间
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.