aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.42k stars 2.12k forks source link

Improve documentation about OAuth logins #1047

Closed jsyrjala closed 5 years ago

jsyrjala commented 6 years ago

Documentation for OAuth logins should be improved:

  1. https://aws.github.io/aws-amplify/media/authentication_guide.html

Section Launching the Hosted UI in React says that "With React, you can simply use withOAuth HOC to launch the hosted UI experience. Just wrap your app’s main component with our HOC"

But actually the example code shows how a button to start OAuth flow is wrapped inside withOAuth function. No mention how make your main app to appear after successfull login.

  1. Documentation only covers how to start OAuth flow (redirecting AWS etc), but it doesn't cover what to do at the end of OAuth flow, when the OAuth redirects back to your application. Things like reading tokens from URL and calling right functions from Auth / AWS libraries with the tokens.
jsyrjala commented 6 years ago

Related issue #705

jsyrjala commented 6 years ago

I can make a PR to improve docs in near future.

powerful23 commented 6 years ago

@jsyrjala yes it would be great if you could provide some sample code to the doc.

eoliphan commented 6 years ago

In the meantime, is there an example/explanation of what needs to happen that could be documented here?

mikereinhold commented 6 years ago

Following @eoliphan's suggestion - while waiting to get it documented, it would be great to have a brief description of how to handle with Amplify after successful login.

For example, getting the tokens from the hosted UI with Implicit grant is easy, but not sure how to get Amplify to recognize and import those tokens for seamless use of other Amplify components (API client for example). Also, how to handle an Authorization Code grant from the hosted UI is less clear: is there an Amplify function to call the TOKEN endpoint and retrieve the tokens?

I'd be happy to create a PR for improving the docs if I can get something working. Alternatively, also willing to create a code PR for missing functionality, if that is the case...

powerful23 commented 6 years ago

@mikepatrick thanks for you feedback. For the first question I think @elorzafe may have the answer. For the second one Amplify will automatically hit the TOKEN endpoint and retrieve the tokens, all you need to do is to call Auth.currentSession() to retrieve those token. Basically there is no difference for you to act either with implicit grant or code grant.

mikereinhold commented 6 years ago

@powerful23, so all we should have to do in the redirect page is call Auth.currentSession()? I thought I had tried that previously, so here we go, trying again:

When I try to do so, the currentSession promise is rejected with "no current user". This is coming from Auth.ts in Amplify, which depends on the underlying CognitoUserPool.getCurrentUser in amazon-cognito-identity-js CognitoUserPool. So... it's looking for the current user from a storage resource, either LocalStorage or CookieStorage. Based on the user pool configuration and initialization in Auth.ts, this should be CookieStorage.

Maybe I'm missing something... but, digging through the code, I don't see 1) how anything could know the authorization code received by my redirect page to provide to the token endpoint or 2) where the token endpoint is being called from either Amplify or amazon-cognito-identity-js

Once I've successfully performed a implicit grant or authorization code grant and backfilled credentials into cookie storage, then Auth.currentSession() will find the last auth user and return the session (if it's still valid) or refresh it (if it's an authorization code grant) - that all makes sense. I just can't see how / where to handle the first authorization code...

Digging deeper.... #841 seems to indicate that it's a mismatch between storage methods. Ok, so try taking out the CookieStorage configuration for Amplify - no dice. Then I notice that the reference there about amazon-cognito-identity-js being the part that does the URL parsing - and a link back to the separate repo for amazon-cognito-identity-js (vs the version included in this repo). Note several differences, including URL parsing for authentication code grant and implicit grant as well as token endpoint handling. It doesn't look like this particular component and functionality came over in the #182 PR that brought over amazon-cognito-auth-js functionality...

Am I seeing this correctly or am I crazy? :)

powerful23 commented 6 years ago

@mikepatrick yes as you have found out that the Cognito Hosted UI is mainly implemented in amazon-congito-auth-js which will parse the callback url (and hit the token endpoint if the type is code authentication) and store those tokens into the Storage object(localStorage or CookieStorage) so Auth.currentSession() will retrieve those tokens from it.

I will try to reproduce it to see if it works as expected. Thanks.

mikereinhold commented 6 years ago

@powerful23 Ok, so... looks like maybe it is working as expected now, but a combination of things made this difficult to get there.

1) It looks like the CookieStorage issue referenced via #841 was my original issue. Either it's not 100% fixed in 0.4.8 or there's some other edge case. This was the original problem I had, though I didn't know it at the time. Post-review 2) While messing around trying different things for above messages... I messed up my Amplify config and the oauth section wasn't being recognized. (facepalm) 3) Once I found that and fixed it, I noticed additional attempts at the Token endpoint. 4) I decided to try removing CookieStorage as per #841. Things are now working as expected!

There are definitely still questions... but things are much happier now. If I can, I'll try to capture more on the scenario where CookieStorage is causing trouble.

From a documentation perspective, a few things would help:

drice commented 5 years ago

@mikereinhold Any tips on how to implement this? It doesn't look like the documentation covers this yet.

LechuckThePirate commented 5 years ago

As an addition to all being discussed, I found that amplify always tries to authorize with "login" endpoint, instead of checking if a current session exists in another app (SSO) and get the grant code directly without having to ask the user "are you XXXX" ?? this is disrupting and should be possible to choose whether to ask the user or not...

I'm doing SSO with another application (C#). If I log in in React with amplify and then I navigate to the C# app, I'm able to retrieve the code from AUTHORIZE without calling LOGIN, and that makes the transition from one site to the other totally seamless, no questions asked I can create the session and get the tokens.

That doesn't happen the other way around (login in C# and navigate to the react site) since the login operation with amplify always ends in LOGIN asking me to confirm if that's the current user...

Is there anyway to bypass that?

powerful23 commented 5 years ago

Hi all, the original request of this thread should have been fulfilled with the current Authentication doc: https://aws-amplify.github.io/docs/js/authentication#social-providers-and-federation

I am going to close this issue. If you have further issue/advise for the doc, please open a new issue in the repo so we can track it better. Thanks!

github-actions[bot] commented 3 years ago

This issue has been automatically locked since there hasn't been any recent activity after it was closed. Please open a new issue for related bugs.

Looking for a help forum? We recommend joining the Amplify Community Discord server *-help channels or Discussions for those types of questions.