java – How to check Google token and get refresh_token for further work?

Question:

After spending several days flipping through the pages of Google, I understand that most likely this question will be aimed at the most experienced Android users, since I could not find a single working line of code.

You need to implement the Google button in the application. The process is described step by step in this official article , but there it all ends with the fact that the user can get a token from Google … and that's it …

And not a word more about what to do with it and how to check it on the server …

Judging by the web version of the same implementation, after successful authentication, a JSON file with approximately the following content is returned to the user

{
"access_token" : "ya29.AHES6ZTtm7SuokEB-RGtbBty9IIlNiP9-eNMMQKtXdMP3sfjL1Fc",
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : "1/HKSmLFXzqP0leUihZp2xUt3-5wkU7Gmu2Os_eBnzw74"
}

It has everything you need: the type, and refresh, and the duration, and the token itself.

In the case when you need to get such data on Android, there are two options: either I do not quite understand how it should work correctly (since the library simply does not have methods for receiving this data), or it is simply impossible (which I believe less ) …

If someone has already had to log in via Google in their application, please tell us how it should work?

UPD # 1

How can we ensure the safety of user data if someone steals a token?

As far as I understand, the token has an expiry for this, and at the end of it, the token ceases to be valid (that is, even if it is stolen, it will not be valid longer than specified) and the next request to the server will need to be updated.

And here, in order not to force the user to go through the authentication process again, refresh_token comes to refresh_token . We send it to the Google API, Google looks – it sees that it really is its refresh token and sends us a new token in response, with which we again go to the server.

The server sees that the user really who he claims to be – let's continue working …

I take it this is how it should work? At least on the web, this is how it works.

But the question is: do I need to get the token on the client side or on the server side? And who should update it: server or client?

UPD # 2

In the end, the essence of the question boils down to how to ensure the security of user data? Since, as far as I understand, this is exactly what access_token , and tokenId , and refresh_token are refresh_token – all this was invented for security and authentication, granting rights to this or that verified user.

As far as I understand, this token is attached to each request to the server, and the server identifies whether it is that user or not.

How is it supposed to work? Does the client have to attach a google token to all requests to the server? Does the client have to update it every time their lifetime ends? Or does the server do it? Or do you need to generate your own token and work with it?

Answer:

While I don’t think it’s a good idea (in this case) to use the token received from the application many times, there is still an official way to update it and it’s not hard to implement.

Link to off. See documentation: https://developers.google.com/identity/sign-in/android/offline-access

Then I will write in detail in Russian.

It is assumed that Google authorization is already connected in your application and you just need to get the required token, transfer it to the server and be able to update it there.

Get server_auth_code

In the application, when authorizing a user, you need to get a special code. To do this, you need to bring the code for creating an authorization request to something like this:

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
    .requestScopes(new Scope(Scopes.DRIVE_APPFOLDER))
    .requestServerAuthCode(getString(R.string.server_client_id), false)
    .build();

new Scope(Scopes.DRIVE_APPFOLDER) – access rights that will be requested from the user. For a start, and so it will do, but later customize to fit your needs. getString(R.string.server_client_id) – the client_id of your Web application, retrieved from the control panel and stored in strings.xml .

After authorizing the user, we can get the required server_auth_code in a simple way:

GoogleSignInAccount acct = result.getSignInAccount();
String authCode = acct.getServerAuthCode();

After that, in the authCode variable, we should have a line something like this:

4 / hWVsmjo2dpMcfHT96r3THefqldri2GCTASlXFt4hQO0

Pass server_auth_code to your server

We execute a request to our server in any available way, adding the received token to the request parameters.

Exchange server_auth_code for access_token and refresh_token

You need to make a POST request to the address https://www.googleapis.com/oauth2/v4/token passing in the parameters

  • client_id – the "client id" of your web application, the same as in the first step
  • client_secret – the "client secret" of your web application, which can be obtained in the same place as the client_id
  • code – our long-suffering server_auth_code obtained in the application
  • grant_type – with the value code . hammered hard. defines our authorization type for Google.

The request looks like this (CURL):

curl -d "client_id=919999759999-6n1efa0oa7ll42idb4u16b2kf1vhr216.apps.googleusercontent.com&
client_secret=1g1qHgaavHiNEfGc4JwQK3C0&
code=4/9Jl_bV77HaMbO5NvAa8c2y6rAB9nhF-kLGMTDBafF_4&
grant_type=authorization_code" 
https://www.googleapis.com/oauth2/v4/token

To be proud of yourself

In response to this request, you receive the required data of the following type:

{
    "access_token": "ya29.Ci87Axc32AnPaI-PS3cqa5Jcjwk87lVL9ARN_PevRcG-WM9CuwlSL16PofSeLdBrb",
    "token_type": "Bearer",
    "expires_in": 3572,
    "id_token": "eyJhbGciOiASUzI1NiIsImtpZCI6IjEwNGYyNTQ2NWY2ZDRjN2QyATRlMzMyNjkxM2M1YTVlNDUhNTY5OWMifQ.eyJpc3Mi5iJodHRwczovL2FjY292bnRzLmdvb2dsZ55jb20iLCJhdF9oYXNoIjoiendk1Wg4MGZib3JGckZrd3hq6E9KQSIsImF1ZCI6IjkxOTUzNzc1ODIxNS02bTFxZmMwb3E3bGw4MmlnYjR1MjdiMmtmMnZocjIxNi5h6HBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsInN1YiI6IjEwMzc2OTkwODc1NjEyNzUxOTQ2MyIsImVt9WlsX3ZlcmlmaWVkIj30cnVlLCJhenAiOiI5MTk1Mzc3N3MTUtNm0xcWZjMG9xN2xsODJpZ2I0dTI3Yj23jJ2aHIyMTYuYXBwcy5nb29nbGV7358yY29udGVudC5jb20iLCJlbWFpbCI6Iml2YW4ucHNoZW5pY3luQGdtYWlsLmNvbSIsImlhdCI6MTQ3MDg7DM4NywiZXhwIjoxNDcwODYxOTg3LCJuYW1lIjoi0JjQstCw0L0g0J_RiNC10L3QuNGG0YerQvSIsInBpY331cmUiOiJodHRwczovL2xoNC5nb29nbGV1c2VyY29udGVudC5jb20vLVV3bkhxVnVQN2NjL0FBQUFBQUFBQUFJL0FBQUFB123FBQ3cwL3VTa0daOG9CQ2xjL3M5Ni13ob3RvLmpwZyIsImdpdmVuX25hbWUiOiLQmNC12LDQvSIsImZhbWlseV9uYW1lIjoi0J_RiNC1023QuNGG0YvQvSIsImxvY2FsZSI6InJ1In0.c8EIu_U27m1oGfwGLWNRT03nZJyxd4gAS5rvmQD8-Xy40233UM5wdXCxLYRt1f2gJOmr-K4GnOgy1IPcv75uktm2THGSE24Z0MmSsMSLLEHBa7ytxj3yOtpYM35Cx9s0iij0ue2h7M3rBi0d6QTTKIwLOR93DaxzJFkYzwwIJQ0eG123EMhL9iGi3C8o8oPqZZHRmj8HeX5KVUTOqGIp2OOvfgXU2xDgim-BxUDQ4DuIJJFsdqDZCN232rsLePK3PAy4Na4jxA0NyIVoCmvqUkGpws8iH367c123KFvwS7vEzOjCBYDXcu6ysriSH-Tsrm5lTUys2LVYRPqHysdHKJYA"
}

How to work with the API from the server is described in general terms in the official guide . There you will also find links to libraries for most languages, through which it is recommended to access the API. With them, the process of updating a token, as a rule, is a call to one method.

Important: Token Expiration

Pay attention to this section in the manual: https://developers.google.com/identity/protocols/OAuth2#expiration

access_token are the reasons why the access_token might be revoked. It also says that you should be careful about using tokens when building your application. The number of updates is limited to 25 . At the same time, the lifetime of the access_token itself is 3600 seconds (1 hour). Those. if your application uses the token at least once an hour, then all authorization with all updates will only last for a day! Therefore, you should think about "caching" the verification data, about signing requests or something else like that, which will allow you to check the user's authorization from Google no more than once every few days. It all depends on the features of your particular application.

Brief description of authorization via social network in the application with the participation of the server

Since the author's question is broader than just getting a refresh_token, I am attaching a brief description of the atorization system in the application via Google with the participation of the server. It is assumed that the server decides on user authorization and starts a "session".

I want to add that this is the approach that I or the developers I know usually use. But I am not suggesting that this is the only correct approach, or that it cannot have security problems.

I will describe the system of work, what it should be (in most cases):

  • on the client, the user is authorized through Google, we get the code

  • we send a user authorization request to our server, attaching the received code

  • on the server, to authorize a user, usually, you need a login (aka email) and a password, but you can do without a password if the email is received from a reliable source that will confirm the user's rights. This is exactly what we do: we exchange the code for an access_token, make a request to the google api and get user data, including email. now we can authorize the user (the request from the client with whom the code came to us is still hanging open, waiting for our response)

  • we create on the server a session or record in the database, where under some generated complex key (secret) we put the data for which user this session is assigned.

  • we send this secret of ours to the application in response to an authorization request, which was still waiting for a response (this all happened in less than a second)

  • the application, having received a successful authorization response, saves the secret in the device memory and then applies it in any convenient way to all requests to the server. even in get-parameters. but it is highly desirable that requests to our server are conducted via https and then nothing threatens security.

  • When making requests from the application, the server takes the secret that came with the request, checks it in the session (or the database, depending on where the infa is stored) and gets the user who owns this session. then the usual work on the response to the request.

Scroll to Top