-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Basic SSO Implementation #5
Comments
I can think of 2 directions to implement: 1. Use FB/Google's client SDKNew client side APIs: They call 3rd party client API for auth, then pass the access token back to skygear-server via Built-in providers:
These built-in providers would check if the access token is valid and create/login a skygear user. 2. Implement the entire oauth flowNew client side APIs: Skygear will provide default
If there is any app-id/api-key/secret/etc, read them from env variables. Skygear client will get the above Server then notifies client side (probably via Pros and cons1. Using 3rd party client SDK
2. Implement the entire Oauth flow
The second one is more generic, and can is suitable if we want to support many different services, seems like this is the case?. But if FB and Google (or the famous one with client SDK) are all we wants, the first one seems to be better? I am personally for 2. |
@b123400 I think 2 sounds better too. For one thing, we will definitely go beyond FB and Google very soon, implementing FB and Google SSO are just a small target to help us build the infrastructure and set the API design sample to implement further SSO. Here are a few questions:
|
Sure. This is not exactly about auth, but a very common scenario with 3rd party login. Instead of just signing in, users may want to call the 3rd party service as well, for example fetch user information from Facebook. Normally when you are only using the Facebook JS SDK, you do something like this:
This works because Now, if we are implementing the entire OAuth flow, the skygear API would looks like this:
It's good that we have the access token, but how to use it? There is no public API for setting the access token into the internal of Facebook SDK. Which means I have to do something like this:
As you can see, access token has to be passed to FB SDK for every request, which is not very convenient. Also, there is no guarantee 3rd party SDK would provide API to input access token, at least I couldn't find an API to pass access token in the Google Javascript API.
Sure. Though I don't think popup is an issue. Facebook's
After some thoughts, Yes we can actually implement both flows. The web-based flow will always be available (I am not sure how limited an environment can be, but as long as they can open an URL, it should works.), and can try to use native mechanism to login by detecting the environment.
The existing AuthProvider should already be able to handle the scenarios.
Do you think it is reasonable to ask user to write the above code?
These are the params I can find in the document, not sure if more is needed in practice.
By implementing both flows, it means when the user calls
|
@b123400 Cool! Some follow-up questions/comments after our discussions today.
To finish this issue, can @b123400 you help:
|
Oh this is nothing about cloud function, this is pure client side, browser only. The server always has access to the access token, and is indepenent on #48. On the server, everything is good. The inconvenience is about Facebook JS SDK, on the client side, on the browser. For example, if you want to login the user then read profile from Facebook, you can implement with this:
Notice there is no server side code involved, everything is browser only. It works by the browser sending a request directly to Facebook's server (with the access token), and get a response back. Look at the above code, there is no mention of the access token, that is because the library is saving it, and using it internally. What happens if we implement the flow in Skygear? We have the access token, we can pass it to the browser, but because we are not Facebook, we cannot access the internal of the
This does not work, because
Now, it works. There is an explicit access token passing, from Skygear JS SDK, to Facebook JS SDK. This explicit access token passing is the inconvenience I was talking about. API ChangesNew APII am just listing the JS API here for simplicity, similar APIs apply to both iOS and Android.
New server options (Editable on portal)
New cloud functions
Extra discussionDo you think we should use |
Also, can you also specify in your plan how it will support mobile SDK? For device login / limited capability devices, take a look at: |
@chpapa wrote:
I am under the impression that we should have a review of the API changes before creating issue for implementation. |
I expect access_token to be a part of the user record, so if the client can get the user, it can get the access_token as well. If you want it to be explicit, how about this, an API named
Client ID should be enough. You need App ID elsewhere (e.g. on the Facebook config page), but skygear-server does not need App ID.
I originally think we should redirect back to the page the user came, but if a callback URL is better, sure it is possible.
We can determind that from env variables, e.g. if
Do we need another client side API?
OK, I didn't get that. |
@cheungpat yes sorry I went too fast |
@b123400 In responds to your comment:
I have no preference on how explicit it should be, but I'm also not sure how to do it now. If you can include how we do it now / new API in the sample code on this issue that would be good for others to comment OR for yourself to decide how explicit it should be?
Actually, I meant we should display OUR callback URL for users of Skygear to copy & paste. (Not an input field for users to set the callback URL) My impression is on Facebook / Google OAuth setting, one setting they required is the users should put a callback URL. Can you help verify?
Your suggestion seems fine. Or is there any existing convention @rickmak ?
Your suggestion sounds fine to me. |
After reading about devices with limited capability, this is the list of new API I propose. JS
iOS
Skygear-serverEnvironment variables
APIs
Login flowJS, iOS and Android should follow this flow: When using 3rd party client
When using OAuth flow
For devices with limited capability
|
Change regarding iOS11 worth a note for our implementation: openid/AppAuth-iOS#120 |
@carmenlau Thanks! Sorry I know it is really late and I have the following question regarding the SSO spec:
Finally, a small comment on the methodology is for API design, it is always good to include sample code for different use cases as a sanity check of how usable are the APIs. |
In the design, only
yes
If we have shorthand like
In the current design, we don't have specific SSO parameters. User only need to provide the provider name e.g.
Right, will try adding this when working on the SDK part. |
@carmenlau thanks for the clarification. |
Agreed implementation direction, discuss offline with @carmenlau
|
Discussion on the callback handling on JS SDKAfter server obtained user information from 3rd party provider and created skygear access token. Server have to send the result back to the browser js sdk. Solution 1:
Solution 2:
Conclusion: We will use solution 2 |
if we choose solution 2, we shall make sure when we support custom domain (#95), the domain added there should also add to the default for the domain whitelist. |
The SSO portal design: The hover effect of SSO provider settings, siu tao gave us 2 version to choose. I prefer version B. Remarks:
|
Related android SDK issue: SkygearIO/skygear-SDK-Android#73 |
…or the oauth and 3rd party sdk login flow SkygearIO#5
Supported flow are - loginOAuthProviderWithRedirect - loginOAuthProviderWithPopup - linkOAuthProviderWithAccessToken - unlinkAuthProvider refs SkygearIO/features#5
Description
Have official plugins for common SSO support; And also make it easy to enable and config them from Skygear Portal.
Related Issues
Portal Design
Portal Features
UX Design
Put (link to) Portal Design here
API Design
Scenario
To be expanded
AuthProvider A
, but the email already got another account fromAuthProvider B
, show an error and tell users to login with anotherAuthProvide B
AuthProvider A
, but the email already got another account fromAuthProvider B
, tell users to login and link with new AuthProviderAuthProvider A
, but the email already got another account fromAuthProvider B
, assume it is two different accounts (will break the assumption of Skygear, which each users got unique email address)AuthProvider
Sample Code
Put sample code of how you vision this API will be used, consider different type of developers and different abstract level
API Design
This is the API I am proposing
JS
loginWithOAuthProvider(providerID, options, [accessToken])
providerID
- A string that identify the login provideroptions
popup
(default), orredirect
redirect
, skygear will redirect the user to this url after auth. If it is null, back to the current URLaccessToken
- Optional. Pass in access token if client already has it, skygear will try to login directly instead of going through the OAuth flow.associateAccountWithProvider(providerID, options)
providerID
- A string that identify the login provideroptions
popup
(default), orredirect
redirect
, skygear will redirect the user to this url after auth. If it is null, back to the current URLgetOAuthTokens()
Return a promise of tokens
Platform specific API
loginWithFacebook(options)
andloginWithGoogle(options)
options
popup
(default), orredirect
redirect
, skygear will redirect the user to this url after auth. If it is null, back to the current URLiOS
-[SKYContainer loginWithOAuthProvider:(NSString*)providerID, options:(NSDictionary*)options completion:(void(^)(NSError*, SKYUser*))]
providerID
- A string that identify the login providercom.facebook
,com.google
options
popup
(default), orredirect
, popup means in-app-browser (SFSafariViewController/WKWebView) and redirect means Safari.app-[SKYContainer loginWithOAuthProvider:(NSString*)providerID, accessToken:(NSString*)accessToken completion:(void(^)(NSError*, SKYUser*))]
accessToken
- Client calls this API if it already has an access token, skygear will try to login directly instead of going through the OAuth flow.-[SKYContainer associateAccountWithProvider:(NSString*)providerID options:(NSDictionary*)options completion:(void(^)(NSError*, SKYUser*))]
providerID
- A string that identify the login provideroptions
popup
(default), orredirect
, popup means in-app-browser (SFSafariViewController/WKWebView) and redirect means Safari.app-[SKYContainer getOAuthTokensWithCompletion:(void(^)(NSError*, NSDictionary*))]
Return tokens
Platform specific APIs
-[SKYContainer loginWithFacebook:(NSDictionary*)options]
and-[SKYContainer loginWithGoogle:(NSDictionary*)options]
options
popup
(default), orredirect
, popup means in-app-browser (SFSafariViewController/WKWebView) and redirect means Safari.appSkygear plugin
Environment variables
UNIQUE_EMAIL_FOR_ACCOUNTS
FACEBOOK_CLIENT_SECRET
GOOGLE_API_KEY
SSO_ENABLED
e.gFACEBOOK,GOOGLE.
APIs
oauth:auth_url
oauth:handle_code
oauth:handle_access_token
Login flow
JS, iOS and Android should follow this flow:
When using 3rd party client
oauth:handle_access_token
, to receive skygear userUNIQUE_EMAIL_FOR_ACCOUNTS
When using OAuth flow
oauth:auth_url
oauth:handle_code
)UNIQUE_EMAIL_FOR_ACCOUNTS
For devices with limited capability
oauth:handle_access_token
UNIQUE_EMAIL_FOR_ACCOUNTS
Progress Tracker
Preparation
Implementation
QA
Documentation
Release
The text was updated successfully, but these errors were encountered: