I read almost everything I could find about C2DM but what I couldn't understand is the auth token which the server needs in order to send a message.
Do I need to pass the server the password of the user in order for him to get the token?
Or am I missing something?
I don't want to ask the user to enter their password (if it's needed than it's pretty easy to do a phising app).
If I do need to send a token is there a way to get it with the accountmanager api?
Thanks.
After some consideration, is it possible I got confused and the auth token is really my gmail account(the developer)?
Take a look at JumpNote example project: http://code.google.com/p/jumpnote/
It has both the client and server side code you can rummage through.
As for the auth token, JumpNote project has helper shell script to get one: http://code.google.com/p/jumpnote/source/browse/trunk/scripts/get_auth_token.sh
This script will ask you for your Google Account credentials, and will retrieve an auth token that you can use for, I don't know, some time.
Related
I am getting into Android development for the first time and am having a blast, of course. I do have a question, though, about the general approach to authentication (for dealing with a backend).
To begin, here is, in a nut shell, what I have worked out.
Using google's documentation (link), I authenticate the user using the google sign in api. I have put the logic mentioned in the reference in my app's main activity. After the onConnected method fires, I have a successfully connected GoogleApiClient.
With the now connected GoogleApiClient, I use a call to GoogleAuthUtil.getToken to get an oath2 token that I use to authenticate requests to my backend. Basically, any time I make an HTTP request to my backend, I include this token as a header. My backend reads this token and uses the Python API google provides for verifying this token. In the backend, I use the email that is embedded in the (now parsed) token to make sure the user to whom that oauth2 token was issued is, in fact, a user of my system.
Now, here are the questions. First, does this sound like a reasonable approach to authentication on the Android platform? What might I be missing? What could go wrong?
The second question is a bit more direct. When I get the oauth2 token from the client app, I store it and use the same token each time an HTTP request to a secured resource is made. Eventually, of course, the token will expire. From some limited testing using the Android emulator, it seems that if I shut down the application and restart it, I am getting the same, expired token back using the GoogleAuthUtil.getToken, rather than getting a fresh token with a new expiration in the future. In my tests, I have had to restart the emulator in order to get a token with a correct expiry. Am I mistaken here? Is there something special I need to do to tell the Google API to issue me a new token? Do I need to disconnect the GoogleApiClient and reconnect it? I hope to avoid doing this in order to limit the number of activities that need to carry the callbacks required to complete this process.
Any words of wisdom here will be greatly appreciated!
after you have got your token you can use Validate Token, and if it responses with an error: 'invalid_token', you can use GoogleAuth.clearToken(Context context, String token) to clear the token and get a new token with the method you are using to get auth token.
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.
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?
I am trying to use the Android account manager for creating my app's own account, so I have studied the example provided in the SDK.
However, I have a little problem understanding how I have to manage the authentication token on the server.
From what I understood when studying the example and reading some tutorials is that the user will have to provide his login and password when he will first log in. Then the account manager will ask my server for a token associated to the user credentials. This token will be stored as the password in the account on the Android device (so the real password is never stored on the device).
Because the tokens expire regularly, I understand that my server has to be able to generate a new token with a login and an expired token. Is that correct? How can I generate a new token from an old one?
Moreover, what should be the structure of the token? How do I generate it? Has the expire time to be stored in the token itself or on my server?
EDIT: If someone has a simple working example to show me, it would help me very much.
Also, if you have other information than the answer below, please post it, as Amokrane Chentir's answer did not help me.
Indeed, calling AccountManager#getAuthToken() results in calling the method getAuthToken() I have to implement in my AbstractAccountAuthenticator's subclass.
EDIT2: I'm still interested by a solution to this problem, 5 months later :)
You can call the method AccountManager#invalidateAuthToken to request a new Auth Token. Also, you don't need to generate an Auth Token yourself, you have to use AccountManager#getAuthToken.
I'd like to be able to send a POST request from an Android app to App Engine and have it linked to the user's Google account. I read that you need to obtain an authentication token and send it with the POST request. Does Android provide a way to request this token? And how would GAE process it?
I feel like this should be easy and I'm missing something obvious.
Thanks!
See my blog post on how to authenticate with an App Engine app using credentials stored in the phone.
It is possible to authenticate users programmatically. In the Python SDK, the appengine_rpc module performs this function. In a nutshell, the procedure is this:
Use ClientLogin to get a one-use authentication token given the user's username and password.
Make a POST request to yourapp.appspot.com/_ah/login, with the arguments continue=http://localhost/&auth=authtoken (where authtoken is the one-use token you got from step 1).
Intercept the 302 response returned and capture the returned Google cookie.
Supply the cookie on all subsequent requests.
For excruciating detail, see the source of appengine_rpc.py, linked above.
As of Android 2.0, you can use AccountManager to request an auth token for accounts of type com.google. You can then authenticate the user to an App Engine app by hitting the url:
http://[yourapp].appspot.com/_ah/login?auth=[theauthtoken]
The cookies set in the response can be piggybacked onto future requests to your app to authenticate the user against your app.
In the absence of sample code that does exactly this, you can check out the Sample Sync Adapter code (bundled with the SDK) for a general idea about requesting auth tokens.
EDIT: Just realized Nick wrote about the second part, but the AccountManager#getAuthToken bit is new as of Android 2.0.