问题描述
我想使用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调用。
那可能吗? 谢谢。
1楼
我已经使用了联合身份进行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'
)
最终,这将为您提供所需的临时访问密钥,秘密密钥和会话密钥。
2楼
我决定使用oAuth。
这是快速而肮脏的完成方式
在AWS Cognito中
1)设置Cognito用户池。 添加App Client,将App Client ID和App 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发送回前端,并将它们保存在本地存储中,并使用它们进行身份验证和完成。