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

时间:2019-02-12 15:03:11

标签: javascript node.js facebook express amazon-cognito

我想使用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调用。

有可能吗?谢谢。

2 个答案:

答案 0 :(得分:0)

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

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并进行getCredentialsForIdentity调用:

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

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

答案 1 :(得分:0)

我决定使用oAuth。

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

在AWS Cognito中

1)设置Cognito用户池。添加 App Client App客户端ID App客户端密钥保存为COGNITO_CLIENT_ID和COGNITO_CLIENT_SECRET

2)转到 Federation>身份提供者,然后添加您的Facebook应用ID和应用密钥(两者都将在Facebook应用面板中找到)

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

4)现在转到应用集成>域名并输入您的自定义域;假设 example-app-debug https://example-app-debug.auth.us-east-1.amazoncognito.com

这就是Cognito的全部内容

没有Facebook部分

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

6)在有效OAuth重定向URIs 中的 Facebook登录>设置中,添加以下URL:https://example-app-debug.auth.us-east-1.amazoncognito.com/oauth2/idpresponse并保存更改

和代码

在浏览器中,登录时将用户重定向到该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}`

此呼叫应使用如下代码返回给您:http://localhost:5000/facebook?code=foo-bar-code将此代码发送到您的后端。

在后端,执行以下操作:

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发送回前端,并将它们保存在本地存储中,并使用它们进行身份验证和完成。