[英]Should I federate cognito user pools along with other social idps, or have social sign in via the userpool itself
I am building a social chat application and initially had a cognito user pool that was federated alongside Google/Facebook. 我正在构建一个社交聊天应用程序,最初有一个与Google / Facebook联合的cognito用户池。 I was storing user data based on the user-sub for cognito users and the identity id for google/facebook.
我正在根据cognito用户的用户sub和google / facebook的身份ID存储用户数据。 Then in my lambda-gql resolvers, I would authenticate via the AWS-sdk:
然后在我的lambda-gql解析器中,我将通过AWS-sdk进行身份验证:
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,
},
});
Because all users are equal and I don't need fine grained controls over access to aws-resources, it seems like it would be preferable to instead have all authentication handled via the userpool and to get rid of the identity pool entirely. 因为所有用户都是相同的,并且我不需要对访问aws资源的细粒度控制,所以似乎最好通过用户池处理所有身份验证并完全摆脱身份池。
For example, if I wanted to ban a user's account, it seems that I would first have to lookup the provider based on identity-id and then perform a different action based on the provider. 例如,如果我想禁止用户的帐户,似乎我首先必须根据identity-id查找提供程序,然后根据提供程序执行不同的操作。
So my questions are: 1. Is this even possible? 所以我的问题是:1。这甚至可能吗? - https://github.com/aws-amplify/amplify-js/issues/565 - https://www.reddit.com/r/aws/comments/92ye5s/is_it_possible_to_add_googlefacebook_user_to/
- https://github.com/aws-amplify/amplify-js/issues/565 - https://www.reddit.com/r/aws/comments/92ye5s/is_it_possible_to_add_googlefacebook_user_to/
There seems to be a lot of confusion, and the aws docs are less clear than usual (which isn't much imo). 似乎存在很多混淆,并且aws文档不像通常那样清晰(这不是很多)。 https://docs.aws.amazon.com/cognito/latest/developerguide/authentication.html
https://docs.aws.amazon.com/cognito/latest/developerguide/authentication.html
It seems that there is clearly a method to do this. 似乎有一种方法可以做到这一点。 I followed the above guide and am getting errors with the hosted UI endpoint, but that's probably on me ( https://forums.aws.amazon.com/thread.jspa?threadID=262736 ).
我遵循了上面的指南,并且在托管的UI端点上出现了错误,但这可能在我身上( https://forums.aws.amazon.com/thread.jspa?threadID=262736 )。 However, I do not want the hosted UI endpoint, I would like cognito users to sign in through my custom form and then social sign in users to click a "continue with fb" button and have that automatically populate my userpool.
但是,我不希望托管的UI端点,我希望cognito用户通过我的自定义表单登录,然后社交登录用户点击“继续使用fb”按钮并自动填充我的用户池。
Then replace the code above with the following to validate all users: 然后使用以下代码替换上面的代码以验证所有用户:
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);
}
});
Auth.federatedSignIn('facebook', { token: accessToken, expires_at }, user)
.then(credentials => Auth.currentAuthenticatedUser())
.then((user) => {
onStateChange('signedIn', {});
})
.catch((e) => {
console.log(e);
});
From what I have seen, there does not appear to be a method with Amplify to accomplish this. 从我所看到的,似乎没有一种方法使用Amplify来实现这一目标。 Is there some way to do this with the aws-sdk?
有没有办法用aws-sdk做到这一点? What about mapping the callback from the facebook api to create a cognito user client-side?
如何映射来自facebook api的回调以创建一个cognito用户客户端? It seems like that could get quite messy.
看起来这可能会变得非常混乱。
If there is no mechanism to accomplish the above, should I federate cognito users with social sign ins? 如果没有机制来实现上述目标,我应该将Cognito用户与社交登录联合起来吗?
And then what should I use to identify users in my database? 然后我应该用什么来识别我的数据库中的用户? Am currently using username and sub for cognito and identity id for federated users.
我目前正在为联合用户使用username和sub for cognito和identity id。 Extracting the sub from the Auth token server-side and then on the client:
从Auth令牌服务器端提取子,然后在客户端上提取:
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);
}
});
If anyone could provide the detailed authoritative answer I have yet to find concerning the use of cognito user pools in place of federating that would be great. 如果有人能够提供详细的权威答案,我还没有找到关于使用认知用户池来代替联合会这将是伟大的。 Otherwise a general outline of the correct approach to take would be much appreciated.
否则,将非常感谢正确的采取方法的大纲。
Here's what I ended up doing for anyone in a similar position, this isn't comprehensive: 这就是我最后为类似职位的人做的事情,这不是很全面:
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);
};
You can then use Auth.currentSession() to get user attributes from the client. 然后,您可以使用Auth.currentSession()从客户端获取用户属性。
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);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.