Skip to content
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

Single Sign On Only Works for Users with Uber app? #104

Closed
bennettl opened this issue Sep 8, 2016 · 10 comments
Closed

Single Sign On Only Works for Users with Uber app? #104

bennettl opened this issue Sep 8, 2016 · 10 comments

Comments

@bennettl
Copy link

bennettl commented Sep 8, 2016

I tried implementing the SDK and running it in the simulator, got this on my logs

2016-09-08 15:36:26.932 GlydeApp[49019:1232400] -canOpenURL: failed for URL: "uberauth://connect?third_party_app_name=Glyde&callback_uri_string=glyde://uber&client_id=[secret...]&login_type=default&scope=profile%20places%20request&sdk=ios&sdk_version=0.5.2" - error: "(null)"

Isn't there a fallback option to use the SafariViewController / web interface for people who don't have the app on their phone?

@itstexter
Copy link

itstexter commented Sep 8, 2016

It looks like you're asking for the request scope, which is a privileged scope. Privileged scopes can only be granted through Single Sign On or with a backend set up for OAuth 2.0.

If you ask for non privileged scopes, like profile, it should fall back to a web interface.

@bennettl
Copy link
Author

bennettl commented Sep 8, 2016

Thanks for the quick response! I was able to see the web view by taking out the request scope. But if our app needs to request rides on behalf of the user, and we want to present a web view for testing on simulator / users who don't have the Uber app, how will we go about it?

Not sure what you mean by having a backend set up? Doesn't the user need to be presented with a UI screen telling them our app needs permission to request rides?

@itstexter
Copy link

itstexter commented Sep 8, 2016

If you want to get the request scope (or any privileged scope) on a device that doesn't have the Uber App installed you'll need to use the Authorization Code Flow type for OAuth 2.0. This requires having a backend set up with a client secret that you use to hit our authorization servers as detailed in our documentation.

A quick summary of how that works: You'd direct a user to our website where they can authorize the scopes you're asking for. If the user accepts these scopes a redirect is issued to your server with an authorization code. The server takes the code and client secret and then exchanges these for an access token. Your server would then have to get this access token to your device for use or your device could make calls to your server which would make Uber requests on the user's behalf.

@itstexter
Copy link

The Uber SDK will display a Webview for you for Authorization Code Flow if you configure an AuthorizationCode callback URI as defined in the README. If the Uber app isn't installed the SDK will open a Webview, when the user presses accept Uber's servers pass on an authorization code to your server based off the callback URI you set. You'll need to define the AuthorizationCode callback URI that points to your server in your info.plist and set your Configuration.setFallbackEnabled(true).

If there's no backend necessary Google might just use Implicit Grant type if the App isn't on the phone, which is what the Uber SDK uses when the developer isn't asking for privileged scopes.

@bennettl
Copy link
Author

bennettl commented Sep 9, 2016

Thanks man for the clear and detail explanation. I think I understand the flow better now. This is a good reference as well: https://d1a3f4spazzrp4.cloudfront.net/uberex/duc/SSO_Flowchart_v1.pdf

The only part that's a bit fuzzy to me is in the flow chart, the "3. Show confirmation" part. I was able to get our Node server to obtain an access token from an authorization code, but I'm not sure exactly how to pass that access token on to the client. When obtaining the access token, I tried setting the redirect URI back to the iOS app, but that didn't work. I can only set the redirect URI back to the server.

@itstexter
Copy link

Oh wow I totally forgot we have those flowcharts. I remember making them but I should definitely use them more when replying to issues, thanks for the reminder!

"3. Show confirmation" probably needs some rewording and explaining. I believe by "show confirmation" it means inside your 3rd party app you can show confirmation of a successful connect. Really it just means you got the Access Token to the app and can start hitting the API.

If the completion you passed into loginManager#login has a nil accessToken and a nil error it means that your server has received the authentication code. Now your client knows it is safe to ask your server for the Access Token so you can make an HTTP request to retrieve it from your server. See the Authorization Code Grant section of the README for example code.

You're right that you can't set the redirect URI back to the iOS app. Without the Uber App the Login server cannot verify who the client asking for the access token is, so it can only redirect the code back to your server. It's up to you to get your Access Token back in your client app's control.

@bennettl
Copy link
Author

Thanks for the thorough responses @itstexter, really appreciate them! Two issues we're running into:

  1. "If the completion you passed into loginManager#login has a nil accessToken and a nil error it means that your server has received the authentication code. Now your client knows it is safe to ask your server for the Access Token so you can make an HTTP request to retrieve it from your server."

If the iOS client gets a nil access token, and immediately calls our server to make an Uber API request, won't there be a race condition? Getting a nil access token on the client means that the server has the authorization code and is starting the process for exchanging it into an access token, but does not necessarily mean the server has the Uber access token.

  1. Once the server receives the authorization callback from Uber and exchanges authorization code for an access token, how does the server know which user the access token is associated with? Can we pass the user id somewhere from client -> uber -> server?

Thanks again man!

@jbrophy17
Copy link
Contributor

Hi @bennettl, some good questions!

  1. This is a potential problem. I would suggest setting up some polling logic, so your client can keep asking your server if it has an access token yet. You could, alternatively, setup some sort of push logic where your server pushes a message down to the client to inform it when it has a token. The implementation is up to you.

  2. There is a state parameter that you can set on your LoginManager, which will be included in the request to your server. You can then use this to match a token back to the client.

Hopefully that makes things clear

@bennettl
Copy link
Author

Thanks @jbrophy17 . Makes sense!

@runningdemo
Copy link

@jbrophy17 @bennettl
Speaking of race condition mentioned by bebbettl:

If the iOS client gets a nil access token, and immediately calls our server to make an Uber API request, won't there be a race condition? Getting a nil access token on the client means that the server has the authorization code and is starting the process for exchanging it into an access token, but does not necessarily mean the server has the Uber access token.

@jbrophy17 Why not provide an option that passes the authorization code back to the client directly, so that client can do the access token exchanging itself. Therefore client can control the flow entirely.

@bennettl Also curious how do you implement the polling logic to get the access token from the server, thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants