Node.js 什么';注册后对用户进行身份验证的正确/标准做法是什么?

Node.js 什么';注册后对用户进行身份验证的正确/标准做法是什么?,node.js,express,jwt,backend,cryptojs,Node.js,Express,Jwt,Backend,Cryptojs,我正在尝试在注册后对用户进行身份验证。正确的或标准的方法是什么 作为实现方法,在步骤3中,如何生成随机哈希以发送给用户电子邮件?我看到两种不同的选择: 加密 JWT令牌 我目前正在使用JWT进行登录,那么使用相同的令牌进行用户验证有意义吗?为什么或者为什么不,如果不是,正确的方法是什么?对于您应该使用加密哈希还是令牌的问题,答案既不是 生成用作验证方法的哈希不需要加密安全,它只需要是不容易猜测的唯一验证哈希。 在过去,我在lib中使用了v4uuid,它工作得很好。您还可以基于用户的一些已知信息,

我正在尝试在注册后对用户进行身份验证。正确的或标准的方法是什么

作为实现方法,在步骤3中,如何生成随机哈希以发送给用户电子邮件?我看到两种不同的选择:

  • 加密
  • JWT令牌

  • 我目前正在使用JWT进行登录,那么使用相同的令牌进行用户验证有意义吗?为什么或者为什么不,如果不是,正确的方法是什么?

    对于您应该使用加密哈希还是令牌的问题,答案既不是

    生成用作验证方法的哈希不需要加密安全,它只需要是不容易猜测的唯一验证哈希。
    在过去,我在lib中使用了v4uuid,它工作得很好。您还可以基于用户的一些已知信息,比如他们的id或电子邮件与一些随机信息连接在一起,比如以毫秒为单位的时间和具有大量长度的随机十六进制字符串,但老实说,当UUID v4正常工作时,构建类似信息所花费的时间是浪费的

    您的散列也不需要是唯一的(对每个用户来说是不同的,但要避免所有潜在的冲突?否)-仅使用散列命中端点不是一个好主意。端点还应该为您的用户获取一个标识符,并结合验证哈希。这样,您就不必担心散列在数据存储中是唯一的。按ID查找用户,检查验证哈希是否匹配,验证。我只建议您以一种您可以在您的终端解码的方式混淆用户的已知信息(例如:base64编码他们的用户ID+电子邮件+一些您使用的常量字符串)

    [编辑]

    验证或确认用户实际上只是要求他们证明他们输入的电子邮件地址(或电话号码)确实存在,并且它属于该用户。这是为了确保用户没有输入错误的信息或注册是垃圾邮件。为此,我们不需要加密身份验证,一个简单的共享秘密就足够了

    存储用户的注册数据时,将生成用于验证帐户的共享机密。这可以是(相对)唯一的任何东西,并且包含足够的长度和熵,不容易猜测。我们没有对稍后将要解包的信息进行编码或加密,我们正在进行文本字符串比较,以确保我们提供给用户的秘密完整地返回给我们。这就是为什么可以使用简单的单向散列。我建议使用UUIDV4,因为此散列的组件是从随机信息生成的(其他版本的UUID使用机器的MAC或时间或其他已知信息)。你可以使用任何你喜欢的方法,只要它不容易被解码或猜测

    生成验证散列后,您将其发送给用户(在一个格式良好的URL中,用户只需单击该URL),以便他们完成帐户注册。URL指南完全取决于您,但以下是一些建议:

    坏的

    /verify/


    /verify?hash=

    由于URL中只有验证哈希,您依赖于此值在数据存储中是全局唯一的。如果您能够可靠地生成从不包含冲突的唯一值,那么这也没关系,但您为什么要担心呢?不要依靠验证哈希本身

    /users//verify/


    /users/?action=verify&hash=

    在这两个示例中,您可以看到重点是提供两个数据,1。是一种识别用户的方法,以及2。您正在检查的验证哈希。
    在这个过程中,首先通过ID在数据存储中查找用户,然后将生成和存储的秘密与URL中给定的值进行比较。如果找到了用户并且验证哈希匹配,那么将他们的帐户设置为活动,就可以继续了。如果找到用户但哈希不匹配。。。您提供的URL格式不正确,或者有人试图强行对您进行验证。你在这里做什么取决于你,但为了安全起见,你可能会重新生成散列并发送一封新的电子邮件,然后重试该过程。这将很快导致一个黑洞,关于如何防止垃圾邮件和滥用您的系统,这是一个不同的对话

    只有当用户ID可以安全地公开显示时,上述URL模式才有效。一般来说,您不应该在URL中使用数据存储ID,特别是如果它们是连续整数。您可以在URL(如UUIDV1)或任何短ID实现中使用许多ID选项

    同时

    一个很好的方法是查看您从其他系统收到的要求您验证自己电子邮件地址的电子邮件,了解这在野外是如何完成的。许多人可能使用以下格式:
    /account/verify/

    在这种情况下,“超长散列”通常由一个库生成,该库创建一个数据存储表只是为了帐户验证(散列存储在该表中),或者解码以显示用户标识符以及某种验证散列。此字符串的编码方式不易反转,因此无法猜测或强制执行。这通常是通过为每个字符串使用某种唯一的salt值对组件进行编码来完成的

    注意-虽然此方法可能是最“安全”的,但我之所以提到此方法,是因为它基于第三方LIB使用的典型方法,而第三方LIB不假设您的用户数据模型。如果需要,您可以实现此样式,但它会更简单