Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 构建一个Slack应用程序,使用OAUTH对外部系统进行身份验证_Node.js_Oauth 2.0_Access Token_Slack_Slack Api - Fatal编程技术网

Node.js 构建一个Slack应用程序,使用OAUTH对外部系统进行身份验证

Node.js 构建一个Slack应用程序,使用OAUTH对外部系统进行身份验证,node.js,oauth-2.0,access-token,slack,slack-api,Node.js,Oauth 2.0,Access Token,Slack,Slack Api,我正在构建一个小型测试松弛应用程序,不清楚身份验证所需的体系结构。这将是一个生活在Heroku上的NodeJS应用程序 当用户使用/slash命令时,它将调用查询外部CRM系统并返回数据的逻辑。为了在这个外部系统中进行身份验证,它需要通过OAUTH流发送用户,以便对数据的访问由调用用户的权限控制 我的困惑在于如何处理或持久化这些身份验证令牌/刷新令牌,这些令牌是我们在此过程中从用户身份验证中获得的 示例步骤: 运行/userbob@gmail.com 检查用户是否已在此外部系统上授权 如果没有,

我正在构建一个小型测试松弛应用程序,不清楚身份验证所需的体系结构。这将是一个生活在Heroku上的NodeJS应用程序

当用户使用
/slash
命令时,它将调用查询外部CRM系统并返回数据的逻辑。为了在这个外部系统中进行身份验证,它需要通过OAUTH流发送用户,以便对数据的访问由调用用户的权限控制

我的困惑在于如何处理或持久化这些身份验证令牌/刷新令牌,这些令牌是我们在此过程中从用户身份验证中获得的

示例步骤:

  • 运行
    /userbob@gmail.com
  • 检查用户是否已在此外部系统上授权
  • 如果没有,请让用户通过外部系统oauth流
  • 在身份验证之后,我们有了令牌,该令牌可用于作为该用户调用外部系统API
  • 进行调用并返回数据
  • 当slack用户运行命令以查看是否已经有了auth/refresh令牌时,我将如何持久化或检查该令牌?如果令牌已经存在,我就不需要再次通过OAUTH流发送它们

    我对方法的看法:

    似乎需要某种类型的数据存储,其中包含slack用户ID、auth令牌和refresh令牌。当用户调用该命令时,我们检查该用户是否在表中,如果在表中,我们使用他们的令牌进行API调用

    如果它们不存在,我们将通过OAUTH流发送它们,以便存储它们

    最后的想法:

    就安全性而言,拥有令牌表是正确的方法吗?如果有人要获得该令牌,它几乎就相当于存储一个纯文本密码


    是否有更好的方法来处理这一问题,或者这是一种常见的方法?

    您的方法是正确的,并且指出了第三方是Salesforce CRM的使用案例

    就安全性而言,拥有代币表是正确的方法吗

    是的,攻击者可能会窃取您的数据库数据。 为了避免这种情况,您可以将令牌存储为加密字符串。 这样,恶意用户应该:

    • 从数据库中窃取数据
    • 窃取您的源代码,以了解您正在使用什么类型的算法来编写令牌及其背后的逻辑
    方法是在整个系统中传播所有信息以获得清除令牌 一个或多个系统可能受到威胁,而不是每个人都受到威胁

    有没有更好的方法来处理这个问题,或者这是一种常见的方法

    通常使用AES-256,详细信息为
    AES-256-gcm
    AES-256-cbc
    。有一些 在性能和用例中,为了选择其中一个,您必须处理它们

    Node.js支持这两种逻辑,示例逻辑可以是:

    const crypto=require('crypto'))
    常量算法='aes-256-gcm'
    常数authTagByteLen=16
    常数ivByteLen=64
    常数keyByteLen=32
    常数saltByteLen=32
    const oauthToken='messagetext'
    const slackUserId='usethisapspassword'
    const salt=加密随机字节(saltByteLen)
    const key=crypto.scryptSync(
    Buffer.from(slackUserId,'base64')。toString('base64'),
    Buffer.from(salt,'base64')。toString('base64'),
    keyByteLen)
    const iv=加密随机字节(ivByteLen)
    const cipher=crypto.createCipheriv(算法,密钥,iv,{authTagLength:authTagByteLen})
    让encryptedMessage=cipher.update(oauthToken)
    encryptedMessage=Buffer.concat([encryptedMessage,cipher.final()]))
    const storeInDb=Buffer.concat([iv,encryptedMessage,cipher.getAuthTag()])。toString('base64'))
    /***
    *
    */
    const storeInDbBuffer=Buffer.from(storeInDb,'base64')
    const authTag=storeInDbBuffer.slice(-authTagByteLen)
    常量iv2=storeInDbBuffer.slice(0,ivByteLen)
    const toDencryptMessage=storeInDbBuffer.slice(ivByteLen,-authTagByteLen)
    const decipher=crypto.createDecipheriv(算法,密钥,iv2,{authTagLength:authTagByteLen})
    解密.setAuthTag(authTag)
    const messagetext=decipher.update(toDencryptMessage)
    破译
    const clearText=messagetext.toString()
    console.log({
    oauthToken,
    storeInDb,
    明文
    })
    
    注意:

    • SALT逻辑将在每次运行时生成一个新的“storeInDb”字符串,而不会影响将来的读取
    • 您可以使用slack用户id作为密码,因此附件也应该知道此信息
    • 例如,您还必须存储salt或编写算法从用户id生成salt
    • salt可能存储在(redis)缓存或其他服务(如S3)中,因此攻击者应该破坏其他系统来解析令牌
    GCM示例由
    您可能会发现

    我是生产Slack应用程序的软件工程师,我们同样使用node.JS和Heroku。为了存储数据,我们使用mongoDB,在mongoDB中我们有一组团队文档,每个文档存储诸如团队id和bot访问令牌之类的信息。我们还有一个用户文档集合,用于存储松弛用户id和身份验证令牌。这就是Slack的建议。看见