我正在尝试为我的Android应用程序写一个基于令牌的auth。为此,我需要一个唯一的令牌,我可以使用它来验证用户。
Itsdangerous库提供了一个JSONWebSignatureSerializer函数,使用它我可以创建JWT令牌。所以我的第一个问题是,将JWT用于基于移动的身份验证是否安全?
其次,我对django rest框架如何生成其令牌进行了一些研究。
def generate_key(self):
return binascii.hexlify(os.urandom(20)).decode()
此令牌是唯一的还是随机的?我应该将哪一个用于基于移动设备的身份验证?
在python中为移动应用程序生成唯一令牌的基本方法是什么?
答案 0 :(得分:2)
查看uuid()库。文档在这里:
https://docs.python.org/2/library/uuid.html
以前对这个问题的讨论如下:
How to create a GUID/UUID in Python
有很多好的细节。
答案 1 :(得分:2)
您可以像提到的内置uuid
模块一样使用。 3.6中发布的新secrets
模块也能够创建唯一的令牌。
from uuid import uuid4
rand_token = uuid4()
下面的函数每次调用时都会创建一个唯一的标记。 os.urandom
方法返回20个随机字节作为字符串,binascii.hexlify
方法将这20个字节中的每一个转换为该字节的2位十六进制表示。这就是返回值的两倍。
如果您想使用此方法并且需要将标记设置为特定长度,请使用您需要的一半作为os.urandom
方法的参数。
def generate_key(self):
return binascii.hexlify(os.urandom(20)).decode()
答案 2 :(得分:1)
好的,这已经过时了,但无论如何我都在打气。您需要决定:您想要独特还是随机?选择一个。
如果您想要唯一,请使用UUID。 UUID的全部目的是确保您生成独特的东西。 UUID代表通用唯一ID。
如果您想要随机的内容,请使用os.urandom
。真正随机的结果不能仅限于唯一性约束!这让他们不是随意的。实际上,它会让它们成为UUID。
现在,对于你的问题,你要求一个身份验证令牌。这意味着您出于安全目的使用它。 UUID是错误的解决方案,生成安全号码是正确的。生成随机数而不是UUID时可能会发生冲突吗?是。但除非你有很多用户,否则它不太可能。你会想要对此进行数学计算,但我的建议是:当你的意思是随机使用时,不要使用UUID。
Oy公司。
答案 3 :(得分:0)
一个可能的解决方案是 AES 加密令牌过期时间 + 用户名,这使得发现过期令牌变得相当容易并且不需要额外的令牌数据库空间
答案 4 :(得分:-1)
我写了一个小辅助函数,用于在django模型中生成唯一标记。您可以使用模型的public static List<Object> GetMembersItems(string ProjectGuid)
{
using (PMEntities context = new PMEntities("name=PMEntities"))
{
var items = context.Knowledge_Project_Members.Include("Knowledge_Project").Include("Profile_Information")
.Where(p => p.Knowledge_Project.Guid == ProjectGuid)
.Select(row => new { IdMember = row.IdMember, UserName = row.Profile_Information.UserName });
return items
.ToList() // this is only needed to make EF happy otherwise it complains about the cast
.Cast<Object>()
.ToList();
}
}
方法调用它。它使用定义的函数生成候选令牌,在数据库中的现有行中搜索该候选令牌。如果找到一个,则再次尝试,否则返回候选字符串。请注意,此处存在较小的竞争条件,但在具有足够大的输出范围的令牌函数中不太可能发生。
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
它甚至支持使用其他生成令牌的方法。例如,如果你想使用完整的uuid,你可以这样简单地调用它:
token = generate_unique_token(MyModelInstance, "token_field_name")