javascript Cognito 托管 UI
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/45926339/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Cognito hosted UI
提问by Fyreye
I have been looking into setting up a login for a web app that lets clients view data hosted in S3 and found that AWS Cognito has a hosted web UI [link]that handles most of the authentication flow for me, the issue I am facing is I cannot find out how to integrate the output of the web UI into my app. Most of the existing documentation in Cognito just references how to use the various APIs in creating your own UI which is leaving me with confusing answers to my issue.
我一直在研究为 Web 应用程序设置登录,该应用程序可让客户端查看 S3 中托管的数据,并发现 AWS Cognito 有一个托管的 Web UI [链接]可以为我处理大部分身份验证流程,我面临的问题是我不知道如何将 Web UI 的输出集成到我的应用程序中。Cognito 中的大多数现有文档只是参考了如何使用各种 API 来创建您自己的 UI,这让我对我的问题的答案感到困惑。
Is there any information that has been created with the Cognito hosted UI in mind?
是否有使用 Cognito 托管 UI 创建的信息?
Amazon says that you can integrate authenticated login with Cognito in minutes but I have been looking at this for a few weeks and cant figure it out.
亚马逊说你可以在几分钟内将经过身份验证的登录与 Cognito 集成,但我已经研究了几个星期,无法弄清楚。
回答by Mike Patrick
I also struggled with this; I agree that the documentation is a little light.
我也为此苦苦挣扎;我同意文档有点轻。
The link you provided shows what your Cognito UI URL might look like:
您提供的链接显示了您的 Cognito UI URL 的外观:
https://<your_domain>/login?response_type=code&client_id=<your_app_client_id>&redirect_uri=<your_callback_url>
The idea is that you send your user to this URI, they do their business, and then they get redirected back to you with some sort of token(s) or code. You can check your domain by clicking "Domain name" in the left nav bar.
这个想法是你将你的用户发送到这个 URI,他们做他们的生意,然后他们用某种令牌或代码重定向回你。您可以通过单击左侧导航栏中的“域名”来检查您的域。
App Client Settings and OAuth Grant Types
应用程序客户端设置和 OAuth 授权类型
First, check your App client settings. You'll need to whitelist your Callback URL(s) (where Cognito will redirect back to), and make sure at least one OAuth Flow is allowed.
首先,检查您的应用程序客户端设置。您需要将回调 URL 列入白名单(Cognito 将重定向回的位置),并确保至少允许一个 OAuth 流。
"Authorization code grant" will return an authorization code, which you then send to the oauth2/tokenendpoint to get an access_token, id_token, and refresh_token. This is a good choice if you have a back-end application and want refresh tokens.
“授权码授予”将返回一个授权码,然后您将其发送到oauth2/token端点以获取 access_token、id_token 和 refresh_token。如果您有后端应用程序并需要刷新令牌,这是一个不错的选择。
"Implicit grant" is what I'm using in my front-end application. It will return an access token and an id token directly to my front-end app.
“隐式授权”是我在前端应用程序中使用的。它将直接向我的前端应用程序返回一个访问令牌和一个 id 令牌。
To use implicit grant, change response_type=codeto response_type=tokenin your Cognito UI URL.
要使用隐式授权,response_type=code请response_type=token在您的 Cognito UI URL 中更改为。
Implicit Grant Example
隐式授予示例
So if your redirect after successful authentication looks like this:
因此,如果您在身份验证成功后的重定向如下所示:
https://localhost:3000/#access_token=eyJraWQiOiJG...&id_token=eyJraWQZNg....&token_type=Bearer&expires_in=3600
You just need to peel the id_token off the URL and send it to Cognito, with your User Pool as the key in the Logins map. In Javascript:
您只需要从 URL 中剥离 id_token 并将其发送到 Cognito,并将您的用户池作为登录映射中的键。在 JavaScript 中:
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: 'us-east-1:bxxxxxx6-cxxx-4xxx-8xxx-xxxxxxxxxx3c',
Logins: {
'cognito-idp.us-east-1.amazonaws.com/us-east-1_ixxxxxxx': idToken
}
});
Where idTokenis the id token that came back to you on the redirect.
idToken重定向时返回给您的 id 令牌在哪里。
Authorization Code Grant Type
授权码授予类型
If you use authorization code grant type instead (response_type=code), your back end will need to call the /oauth2/tokenendpoint to exchange the code for tokens. That call would look something like this:
如果您改用授权代码授予类型 (response_type=code),您的后端将需要调用/oauth2/token端点来交换令牌代码。该调用看起来像这样:
curl -X POST \
https://<my-cognito-domain>.auth.us-east-1.amazoncognito.com/oauth2/token \
-H 'content-type: application/x-www-form-urlencoded' \
-d 'grant_type=authorization_code&scope=email%20openid%20profile&redirect_uri=https%3A%2F%2Flocalhost%3A3000%2F&client_id=15xxxxxxxxxxxxxx810&code=54826355-b36e-4c8e-897c-d53d37869ee2'
Then you can give this id token to Cognito as above.
然后您可以将这个 id 令牌提供给 Cognito,如上所述。
UI Notes
用户界面注释
My application is popping up the Cognito UI in a new tab when the user clicks a link. When the redirect comes back to my app, I use postMessage()to send the tokens to the parent window, which then closes the new tab. I think this is a relatively common pattern.
当用户单击链接时,我的应用程序会在新选项卡中弹出 Cognito UI。当重定向返回到我的应用程序时,我使用postMessage()将令牌发送到父窗口,然后关闭新选项卡。我认为这是一种比较常见的模式。
I haven't tried it, but I'm guessing rendering the UI into an iframe is disallowed, as a mitigation against click-Hymaning. Source
我还没有尝试过,但我猜不允许将 UI 渲染到 iframe 中,以缓解点击劫持。 来源
I hope this is at least somewhat helpful. Good luck!
我希望这至少有点帮助。祝你好运!
回答by Cristian Sepulveda
I implemented this flow, not using Amplify, just using Cognito Hosted UI:
我实现了这个流程,没有使用 Amplify,只是使用 Cognito Hosted UI:
- User navigates in my website (tab 1), and in any page user clicks the login/register button.
- A new tab(Tab 2) is open with the cognito hosted UI using my own domain (auth.example.com)
- Then user makes their business on hosted ui (login/new account/recover password,etc)
- Cognito send a HASH in the URL (with many tokens) to my site callback.(https://example.com/login)
My site process the tokens: The trick is to create an Auth instance, this one can parse the hash and create the user on the LocalStorage:
// mysite.com/login import {CognitoAuth} from 'amazon-cognito-auth-js'; // Configuration for Auth instance. var authData = { UserPoolId: 'us-east-1_xxxx', ClientId: '1vxxxxx', RedirectUriSignIn : 'https://example.com/login', RedirectUriSignOut : 'https://example.com/logout', AppWebDomain : 'example.com', TokenScopesArray: ['email'] }; var auth = new CognitoAuth(authData); //Callbacks, you must declare, but can be empty. auth.userhandler = { onSuccess: function(result) { }, onFailure: function(err) { } }; //Get the full url with the hash data. var curUrl = window.location.href; //here is the trick, this step configure the LocalStorage with the user. auth.parseCognitoWebResponse(curUrl); window.top.close();After the user has been set in the Local Storage, the callback(tab 2) is closed.
On my site (tab 1) I configure an EventListener to listen if there is a change in the Local Storage.
constructor() { window.addEventListener('storage', this.userLogged); } userLogged(event) { if (event.key.indexOf('CognitoIdentityServiceProvider') !== -1) { var data = { UserPoolId: 'us-east-1_xxxxx', ClientId: 'xxxxx' }; var userPool = new CognitoUserPool(data); //behind the scene getCurrentUser looks for the user on the local storage. var cognitoUser = userPool.getCurrentUser(); } }- With cognitoUser you are done, because you can retrieve credentials or other data.
- 用户在我的网站(选项卡 1)中导航,并在任何页面中单击登录/注册按钮。
- 使用我自己的域 (auth.example.com) 使用 Cognito 托管 UI 打开一个新选项卡(Tab 2)
- 然后用户在托管 ui 上开展业务(登录/新帐户/恢复密码等)
- Cognito 将 URL 中的 HASH(带有许多令牌)发送到我的站点回调。(https://example.com/login)
我的站点处理令牌:诀窍是创建一个 Auth 实例,这个实例可以解析哈希并在 LocalStorage 上创建用户:
// mysite.com/login import {CognitoAuth} from 'amazon-cognito-auth-js'; // Configuration for Auth instance. var authData = { UserPoolId: 'us-east-1_xxxx', ClientId: '1vxxxxx', RedirectUriSignIn : 'https://example.com/login', RedirectUriSignOut : 'https://example.com/logout', AppWebDomain : 'example.com', TokenScopesArray: ['email'] }; var auth = new CognitoAuth(authData); //Callbacks, you must declare, but can be empty. auth.userhandler = { onSuccess: function(result) { }, onFailure: function(err) { } }; //Get the full url with the hash data. var curUrl = window.location.href; //here is the trick, this step configure the LocalStorage with the user. auth.parseCognitoWebResponse(curUrl); window.top.close();在本地存储中设置用户后,回调(选项卡 2)关闭。
在我的站点(选项卡 1)上,我配置了一个 EventListener 来监听本地存储是否发生变化。
constructor() { window.addEventListener('storage', this.userLogged); } userLogged(event) { if (event.key.indexOf('CognitoIdentityServiceProvider') !== -1) { var data = { UserPoolId: 'us-east-1_xxxxx', ClientId: 'xxxxx' }; var userPool = new CognitoUserPool(data); //behind the scene getCurrentUser looks for the user on the local storage. var cognitoUser = userPool.getCurrentUser(); } }- 有了 cognitoUser,您就大功告成了,因为您可以检索凭据或其他数据。
回答by Otto
That use case, putting Cognito in front of S3, using the hosted UI, is covered in this AWS blog: https://aws.amazon.com/blogs/networking-and-content-delivery/authorizationedge-using-cookies-protect-your-amazon-cloudfront-content-from-being-downloaded-by-unauthenticated-users/
此 AWS 博客介绍了使用托管 UI 将 Cognito 置于 S3 前面的用例:https: //aws.amazon.com/blogs/networking-and-content-delivery/authorizationedge-using-cookies-protect -your-amazon-cloudfront-content-from-being-downloaded-by-unauthenticated-users/
The blog contains sample code you can steal from. And you can deploy the sample solution easily using the serverless application repository.
该博客包含您可以窃取的示例代码。您可以使用无服务器应用程序存储库轻松部署示例解决方案。
Disclaimer: I authored that blog. Hope it can be of use to you!
免责声明:我撰写了该博客。希望对你有用!
回答by BryceH
You can find more detail about how to make this work here -
您可以在此处找到有关如何进行此工作的更多详细信息 -
http://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-ux.html
http://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-ux.html

