Javascript 我应该联合cognito用户池和其他社交IDP,还是通过用户池本身进行社交登录
我正在构建一个社交聊天应用程序,最初有一个cognito用户池,与Google/Facebook联合。我是基于cognito用户的user sub和google/facebook的identity id来存储用户数据的。然后在我的lambda gql解析器中,我将通过AWS sdk进行身份验证:Javascript 我应该联合cognito用户池和其他社交IDP,还是通过用户池本身进行社交登录,javascript,amazon-web-services,jwt,amazon-cognito,aws-amplify,Javascript,Amazon Web Services,Jwt,Amazon Cognito,Aws Amplify,我正在构建一个社交聊天应用程序,最初有一个cognito用户池,与Google/Facebook联合。我是基于cognito用户的user sub和google/facebook的identity id来存储用户数据的。然后在我的lambda gql解析器中,我将通过AWS sdk进行身份验证: AWS.config.credentials = new AWS.CognitoIdentityCredentials({ IdentityPoolId: process.env.IDENT
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: process.env.IDENTITY_POOL_ID,
Logins: {
[`cognito-idp.us-east-1.amazonaws.com/${
process.env.COGNITO_USERPOOL_ID
}`]: Authorization,
},
});
因为所有用户都是平等的,而且我不需要对aws资源的访问进行细粒度的控制,所以似乎更可取的做法是通过userpool处理所有身份验证,并完全取消标识池
例如,如果我想禁止一个用户的帐户,似乎我必须首先根据身份id查找提供者,然后根据提供者执行不同的操作
因此,我的问题是:
1.这可能吗?
-
-
这里似乎有很多混乱,aws文档也不像平常那么清晰(这在国际海事组织中并不多见)。
似乎有一种方法可以做到这一点。我遵循了上面的指南,发现托管UI端点出现错误,但这可能是我的错()。但是,我不希望托管UI端点,我希望cognito用户通过我的自定义表单登录,然后社会登录用户单击“continue with fb”按钮并自动填充我的用户池
然后用以下代码替换上述代码以验证所有用户:
const validate = token => new Promise(async (resolve) => {
const {
data: { keys },
} = await axios(url);
const { sub, ...res } = decode(token, { complete: true });
const { kid } = decode(token, { header: true });
const jwk = R.find(R.propEq('kid', kid))(keys);
const pem = jwkToPem(jwk);
const response = res && res['cognito:username']
? { sub, user: res['cognito:username'] }
: { sub };
try {
await verify(token, pem);
resolve(response);
} catch (error) {
resolve(false);
}
});
如果有人能提供我尚未找到的关于使用cognito用户池代替联邦的详细权威答案,那将是非常好的。否则,我将非常感谢您提供一份正确方法的总体概述。以下是我最终为处于类似职位的任何人所做的工作,这并不全面:
Auth.federatedSignIn('facebook', { token: accessToken, expires_at }, user)
.then(credentials => Auth.currentAuthenticatedUser())
.then((user) => {
onStateChange('signedIn', {});
})
.catch((e) => {
console.log(e);
});
Auth.currentSession()
.then((data) => {
const userSub = R.path(['accessToken', 'payload', 'sub'], data);
resolve(userSub);
})
.catch(async () => {
try {
const result = await Auth.currentCredentials();
const credentials = Auth.essentialCredentials(result);
resolve(removeRegionFromId(credentials.identityId));
} catch (error) {
resolve(false);
}
});
const authenticate = callbackFn => () => {
const domain = process.env.COGNITO_APP_DOMAIN;
const clientId = process.env.COGNITO_USERPOOL_CLIENT_ID;
const type = 'token';
const scope = 'openid phone email profile aws.cognito.signin.user.admin';
const verification = generateVerification();
const provider = 'Facebook';
const callback = `${window.location.protocol}//${
window.location.host
}/callback`;
const url = `${domain}/authorize?identity_provider=${provider}&response_type=${type}&client_id=${clientId}&redirect_uri=${callback}&state=${verification}&scope=${scope}`;
window.open(url, '_self');
};
useEffect(() => {
// eslint-disable-next-line no-undef
if (window.location.href.includes('#access_token')) {
const callback = () => history.push('/');
newAuthUser(callback);
}
}, []);
/* eslint-disable no-undef */
import { CognitoAuth } from 'amazon-cognito-auth-js';
import setToast from './setToast';
export default (callback) => {
const AppWebDomain = process.env.COGNITO_APP_DOMAIN;
// https://yourdomainhere.auth.us-east-1.amazoncognito.com'
const TokenScopesArray = [
'phone',
'email',
'profile',
'openid',
'aws.cognito.signin.user.admin',
];
const redirect = 'http://localhost:8080/auth';
const authData = {
ClientId: process.env.COGNITO_USERPOOL_CLIENT_ID,
AppWebDomain,
TokenScopesArray,
RedirectUriSignIn: redirect,
RedirectUriSignOut: redirect,
IdentityProvider: 'Facebook',
UserPoolId: process.env.COGNITO_USERPOOL_ID,
AdvancedSecurityDataCollectionFlag: true,
};
const auth = new CognitoAuth(authData);
auth.userhandler = {
onSuccess() {
setToast('logged-in');
callback();
},
onFailure(error) {
setToast('auth-error', error);
callback();
},
};
const curUrl = window.location.href;
auth.parseCognitoWebResponse(curUrl);
};
const decode = require('jwt-decode');
const jwt = require('jsonwebtoken');
const jwkToPem = require('jwk-to-pem');
const axios = require('axios');
const R = require('ramda');
const logger = require('./logger');
const url = `https://cognito-idp.us-east-1.amazonaws.com/${
process.env.COGNITO_USERPOOL_ID
}/.well-known/jwks.json`;
const verify = (token, n) => new Promise((resolve, reject) => {
jwt.verify(token, n, { algorithms: ['RS256'] }, (err, decoded) => {
if (err) {
reject(new Error('invalid_token', err));
} else {
resolve(decoded);
}
});
});
const validate = token => new Promise(async (resolve) => {
const {
data: { keys },
} = await axios(url);
const { sub, ...res } = decode(token, { complete: true });
const { kid } = decode(token, { header: true });
const jwk = R.find(R.propEq('kid', kid))(keys);
const pem = jwkToPem(jwk);
const response = res && res['cognito:username']
? { sub, user: res['cognito:username'] }
: { sub };
try {
await verify(token, pem);
resolve(response);
} catch (error) {
logger['on-failure']('CHECK_CREDENTIALS', error);
resolve(false);
}
});
const checkCredentialsCognito = Authorization => validate(Authorization);