I'm trying Google Plus sign-in in an Android app (with backend support).
I could get access token and email from the user, but know I don't know how should I recognise this user from the server. I'm sending this to the server (email and oauth token) with a POST throught SSL
Of course I could recognise them with their email, but that would open the doors for everyone how knows another email that's on the database.
How could I verify that the user's correctly authenticated and has sent me the correct oauth token for this email?
Thanks!
Two thoughts:
1) Generally, you shouldn't be sending the auth token over the wire if you can help it. Instead you should be using a hybrid flow where the client gets a one time code when it authenticates, passes you this one time code, and you can redeem this for an auth token and a refresh token. Using this method, your server also has offline access on behalf of the user. See https://developers.google.com/+/web/signin/server-side-flow for details. However, I'm not entirely sure how this works with the Android library.
2) Regardless of (1), generally what you can do is to use the plus.people.get method on the server with the userID of "me" to get the user's userID and verify this against what you're expecting. See https://developers.google.com/+/api/latest/people/get for more details.
Yours is a perfect case to use the Authorization code flow.
See this link. It has some workflow diagrams that you might want to see. In your case the user should authenticate and receive an authorization code (and not a token!).
He would then send the authorization code to your server, you can exchange this code for access + refresh tokens. Have your client registered for the scope and have the client credentials.
The access token flow (called the implicit grant flow) is generally used when requests need to be sent directly from the user's browser.
And, as #Prisoner already mentioned, you will have offline access too. That would be a much better design.
EDIT - you might also want to take a look at What is the difference between the 2 workflows? When to use Authorization Code flow?
Related
I'd like to a make a mobile app that makes requests on behalf of a user. I understand the following OAuth flow:
Open user in web view to give my app access to make requests on their behalf
When they hit grant access, my server side app will receive a call with an authorization code
My server side app then needs to exchange the authorization code for an access token
My confusion starts in Step 2. Uber makes a request to my endpoint with the authorization code, but I have no way of knowing what user that authorization belongs to. I can exchange it for an access token and store it in a DB for 30 days, but I have no way of getting it back to the user to use to make requests.
One thought was I could have the user sign in to my app with an email address which I could then use as a key to get the appropriate access token from my server app, but I have no way of associating the access token with an email address in my DB table in the first place.
I'm wondering what the best practices are here. How is my mobile app supposed to know what access token to use for a given user?
(I reached out to Uber API support directly, but they asked me to open a StackOverflow question instead)
Obviously this is kind of a broad question and is highly dependent on what type of app you're building, what you want the user-flow to look like, etc etc but I'll do my best to point you in the right direction.
First, the Uber API has the /v1/me endpoint which will return the users first name, last name, and email address, among other things. So one possible flow is that a User opens your app, they then go through the whole OAuth flow, and once you exchange the authorization code for an access token you immediately use it (from the server) to make a call out to the /v1/me endpoint and then use either the users email address or UUID as a key in your database. If you used email address, you could just allow users to login to your app using this same email address and allow the account creation process to just be the OAuth flow.
I'm not a mobile developer, but my understanding of embedded web views is that they can use cookies just like any other browser. In that case, another thing you could use is sessions / cookies. Assuming you have some kind of identifier for your existing users, you could add that as a cookie for your web server and then when your user gets redirected to your web server with the authorization code, the attached cookie will tell you which user to associate the access token.
Finally, the Uber developer platform includes a state parameter in the authorization phase of the OAuth flow as seen here https://developer.uber.com/docs/authentication You could do something similar to what I describe in the previous paragraph, except instead of using cookies you could store the user identifier in the state parameter and it'll be sent back to you when the user re-directs. You can use that piece of information to tie the access token back to a specific user in your DB.
I hope that helps! Don't hesitate to reach out if you're still confused.
Cheers!
I'm using Google+ authentication in my app to allow a user to sign in, and have access to their 'data' on my server.
The authentication process following the following steps:
User logs in using Google+ on the app, and receives an access token.
The user passes this token to the server.
The server uses this token to verify that the user is who they say they are (following the process shown here). The server can return the data as needed.
This is the part I'm stuck on - How do I verify that the user is who they say they are for future requests without making a request to Google's servers every time? Do I return a session token to the client application that is used, and regenerate the token after some amount of time?
Absolutely. Sending a session cookie is exactly the thing to do.
You will want to use ID tokens to verify that the user is who they say they are. There is a sample project in Java on Github to demonstrate this.
Also, you should be passing a one-time authorization code to your server, not access tokens. See the documentation for getting your server side tokens from an Android app. When you have that code, you send that to your backend and then exchange that one-time code for the server's own copies of access and refresh tokens for that user. Because you receive the tokens directly from Google on your backend they are more secure than having to send between mobile apps and your backend.
My Android app needs to send an authorization code to my server so that the server can use that to acquire an access token for the user's Google Drive account. I have been trying to figure out how to acquire the authorization code and I found this in the Google API documentation (Using OAuth 2.0 for Installed Applications):
This sequence starts by redirecting a browser (system browser or
embedded in the application as a web view) to a Google URL with a set
of query parameters that indicate the type of Google API access the
application requires. Like other scenarios, Google handles the user
authentication and consent, but the result of the sequence is an
authorization code. The authorization code is returned in the title
bar of the browser or as a query string parameter (depends on the
parameters sent in the request).
After receiving the authorization code, the application can exchange
the code for an access token and a refresh token. The application
presents its client_id and client_secret (obtained during application
registration) and the authorization code during this exchange. Upon
receipt of the refresh token, the application should store it for
future use. The access token gives your application access to a Google
API.
Now I am not sure how to get this authorization code in my Android app since the Android examples I have seen seem to get the access tokens directly. I am looking at the Android AccountManager class and it has a method getAuthToken but this seems to refer to the access token and not the authorization code.
So how does one acquire the authorization code that can be shared with a server? If it is possible I would greatly appreciate some example code. If this is not possible what are the possible workarounds?
You may want to take a look at the Cross-client Identity document. It should keep you from needing to pass user tokens back and forth.
I believe you can actually take the access token returned by the Android AccountManager, send this to your server, then have your server make a call against the Google Drive API using that same access token - it is a bearer token and not bound to the channel that created it, so please take good care of it and only send over encrypted connections.
Documentation on how to get that access token can be found here:
https://developers.google.com/drive/quickstart-android
While that access token is good for immediate use, it will expire in less than 1 hour, so if you are looking for a solution that enables your backend server to have continued access to the Drive data, without the user being present at your app at the time of request, an alternate approach will be needed.
I am trying to get Authorization for Google Buzz,Contacts from an Android application.
The flow is similar to this.
The user chooses if he wants to use Buzz.
Using OAuth/Client Auth, we need to get a one-time authorization code.
This code would be used by a web service to periodically read Buzz feeds.
Now, the problem is how do I obtain the authorization code (Not temporary token) from the Android App and send it to the webservice.
I could use the normal OAuth2.0 and use my webservice as the redirect URL to obtain the code. But in that case how can I let the webservice know that the code pertains to which user?
Can I pass extra information with the OAuth dance?
I strongly recommend using OAuth 2. The flow is much better for the end user and it's a lot easier to implement something like this. Additionally, it uses bearer tokens, which means that you can maintain your refresh token server side where it's actually secure and only ship access tokens to the Android when they're needed.
The downside of this approach is that effectively every time your app loads it needs to phone home to get the latest access token. But once it has that access token, it can make whatever API calls it needs to, directly to the Buzz and Contacts APIs.
However, to do this, you don't pass extra information with the OAuth dance. Instead, your Android app needs to have already securely identified which user is signed in with your app, and then make sure the server only ever sends back access tokens associated with the authenticated user. If it doesn't have an up-to-date access token for that user, it would need to make a request out to Google's authorization server to get the latest access token, and then pass it up to the client. So there's certainly a strong potential for some latency there, because that generally needs to be a synchronous call, but that's usually a small price to pay for the advantages OAuth 2 gives you over OAuth 1.
I'm writing an Android application that I want to be able to send requests to a Google App Engine application. In order to do this, the Android app needs to authenticate the user (should be able to just use their Google Account). I'm not sure I'm doing it right, but this is the only way I've found so far:
Post email, password, etc. to https://www.google.com/accounts/ClientLogin
Obtain an authorization token from the aforementioned address
Use the authorization token in the header of the requests to the AppEngine application
But this isn't working (users.get_current_user() still returns None). Is there a right way to do it?
The approach you describe is almost correct. Instead, you need to:
Submit the credentials to ClientLogin and get back the authorization token.
Submit the authorization token to /_ah/login and get back a cookie (and 302 redirect).
Use the returned cookie on all subsequent requests.
This is the process appcfg uses - see appengine_rpc.py for an example of how to use it (and a module you can use, if you're using Python) - specifically, the _Authorize function.