当前位置: 代码迷 >> JavaScript >> 如何使用Facebook使用Cognito对API调用进行身份验证?
  详细解决方案

如何使用Facebook使用Cognito对API调用进行身份验证?

热度:101   发布时间:2023-06-07 17:56:03.0

我想使用Cognito对用户进行身份验证,并可以选择使用Facebook。 用户可以使用这些选项之一进行登录/注册。

我创建了Cognito用户池和Cognito联合身份,还创建了Facebook App进行身份验证。 用户池和Facebook应用程序都连接到联合身份。

当我sign_up并稍后通过Cognito用户池对Cognito用户进行身份验证时,Cognito返回accessToken,我将其存储在前面的localStorage中,并在需要进行认证时使用。

我有/authenticate端点(快速),它接受用户名和密码,如果一切顺利,则返回accessToken。 每当我进行需要身份验证的API调用时,我都会发送本地存储中具有的accessToken。 它或多或少是这样的:

// POST user/authenticate
const authenticationData = {
  Username: username,
  Password: password
}

authenticationDetails = new AuthenticationDetails(authenticationData)

const userData = {
  Username: username,
  Pool: userPool()
}
cognitoUser = new CognitoUser(userData)

cognitoUser.authenticateUser(authenticationDetails, {
  onSuccess: (res) => resolve(res), // here I get accessToken
  onFailure: (err) => {
    console.log('[authenticateUser error]', err)
    reject(err)
  },
//...

然而

当我使用Facebook时,没有获得可以以相同方式使用的accessToken。 我通过FB.login从Facebook获得accessToken,将其传递给Cognito进行身份验证,然后我不知道该怎么做,因为我无法获得任何可用于身份验证API调用的令牌,而这些令牌需要Cognito身份验证。

这是我的工作:

await window.FB.login((response) => { 
  props.userFacebookSignIn(response)
})
// ...

call(foo, 'users/facebook_sign_in', { accessToken: payload.facebookAccessToken })
// ...

// users/facebook_sign_in
AWS.config.region = config.AWSRegion
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
  IdentityPoolId: 'foo',
  Logins: {
    'graph.facebook.com': facebookAccessToken
  }
})

AWS.config.credentials.get((err) => {
  // Here I get no errors, I presume that I have logged Facebook user in 
  const accessKeyId = AWS.config.credentials.accessKeyId
  const secretAccessKey = AWS.config.credentials.secretAccessKey
  const sessionToken = AWS.config.credentials.sessionToken
  // here I can do stuff probably, 
  // but I would like to receive token that would allow me to do stuff, 
  // rather than context I can do stuff in
})

当我完成所有这些工作时,我有一种感觉,即AWS的开发人员将Cognito实施为前端解决方案,而不是在后端使用。 如果我错了,请纠正我。

不过,我希望能够在快速中间件中互换使用Cognito和Facebook来验证api调用。

那可能吗? 谢谢。

我已经使用了联合身份进行Salesforce单点登录,但是我想这些步骤将是相同的。 在通过facebook进行身份验证后,您将收到他们的响应和id_token作为响应。 您必须在方法中将此作为参数传递:

var params = {
  IdentityPoolId: 'STRING_VALUE', /* required */
  AccountId: 'STRING_VALUE',
  Logins: {
    '<IdentityProviderName>': 'STRING_VALUE',
    /* 'graph.facebook.com': ... */
  }
};
cognitoidentity.getId(params, function(err, data) {
  if (err) console.log(err, err.stack); // an error occurred
  else     console.log(data);           // successful response
});

结果,您将获得一个身份ID,您可以将其保存在某个地方,这样就不必在身份验证时每次都进行此调用。 现在获取此标识ID,并进行调用:

response = client.get_credentials_for_identity(
    IdentityId='string',
    Logins={
        'string': 'string'
    },
    CustomRoleArn='string'
)

最终,这将为您提供所需的临时访问密钥,秘密密钥和会话密钥。

我决定使用oAuth。

这是快速而肮脏的完成方式

在AWS Cognito中

1)设置Cognito用户池。 添加App Client,App Client IDApp Client Secret保存为COGNITO_CLIENT_ID和COGNITO_CLIENT_SECRET

2)转到“ 联盟”>“身份提供者”,然后添加您的Facebook应用ID和应用密钥(在Facebook应用面板中都可以找到)

3)转到“ 应用程序集成”>“应用程序客户端设置 ”,单击“全选”,设置回调URL ,我的是localhost:5000 / facebook,还选择“ 授权代码授予”和“ 允许的OAuth范围” (保存范围为:COGNITO_SCOPES)

4)现在转到“ 应用程序集成”>“域名”,然后输入您的自定义域; 假设example-app-debug为: :

这就是Cognito的全部内容

没有Facebook部分

5) 设置>基本,将example-app-debug.auth.us-east-1.amazoncognito.com添加到您的应用域 -保存更改

6)在Facebook登录> 有效OAuth重定向URI中的 设置中,添加以下URL: : 并保存更改

和代码

在浏览器中,登录w时将用户重定向到该URL。 单击Facebook按钮:

window.location.href =
  `https://example-app-debug.auth.us-east-1.amazoncognito.com/oauth2/authorize` +
    `?identity_provider=Facebook` +
    `&redirect_uri=http://localhost:5000/facebook` +
    `&response_type=code` +
    `&client_id=${COGNITO_CLIENT_ID}` +
    `&scope=${COGNITO_SCOPES}`

此调用应使用如下代码返回给您: 将此代码发送到您的后端。

在后端,执行以下操作:

const axios = require('axios')
const url = `` +
`https://${COGNITO_CLIENT_ID}:${COGNITO_CLIENT_SECRET}` + 
`@example-app-debug.auth.us-east-1.amazoncognito.com/oauth2/token` +
`?grant_type=authorization_code` + 
`&code=foo-bar-code` + // <- code that came from Facebook
`&redirect_uri=http://localhost:5000/facebook` +
`&client_id=${COGNITO_CLIENT_ID}`

const response = await axios.post(url) 
// response should have access_token, refresh_token and id_token in data

您将access_token,refresh_token和id_token发送回前端,并将它们保存在本地存储中,并使用它们进行身份验证和完成。

  相关解决方案