📜 ⬆️ ⬇️

Log in via Google to Android and check the token on the server

Recently, I wanted to create a personal project on an android, and the main question was: how to uniquely identify a user, forcing him to do as little gestures as possible? Of course this is a google account. I tried to try many examples on the network - however, the API was updated several times during its existence, many methods did not work, my questions on Google+ about this were either not perceived by the environment at all, or were like "I have never done this before."
In this article I will try as simple as possible for beginners (like me) to describe my method of logging into Google for android, getting a token and checking this same token on the server.

Little preparation


For starters, you must have Google Play Services installed in the SDK. After installing them, you can import all the necessary libraries. The article is written with the expectation of Android Studio - he himself suggests what you need to import.
You must have created an activation with a button.
To make it more familiar to the user, you can create a standard Google+ button Sing-In
It will look like this:
image
Just add to your layout:
<com.google.android.gms.common.SignInButton android:id="@+id/sign_in_button" android:layout_width="match_parent" android:layout_height="wrap_content"/> 


Add an action to the button


We write in our activity:
 View btn = (View) findViewById(R.id.sign_in_button); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = AccountPicker.newChooseAccountIntent(null, null, new String[]{"com.google"}, false, null, null, null, null); startActivityForResult(intent, 123); } }); 

Actually assign an action to the button - a call to an intend to select an account. If you are working in Android Studio, it will tell you which libraries you need to import, so I will not describe this in detail here.
startActivityForResult (intent, 123); - sets the code with which the return will occur. 123 is the return code, it can be anything. This is necessary when you do multiple indents, and you need to process them in different ways.
')

Required access areas


Announce these variables in class. These are the areas of access we need. The first is written in google: “Allows you to identify an authenticated user. To do this, when calling an API, you must specify me instead of a Google+ user ID. »We need the second permission to receive personal user data (Name, Last Name, G + page address, avatar), and the last to receive E-mail. I found this important, because it is quite a constant identifier for writing to the database.
  private final static String G_PLUS_SCOPE = "oauth2:https://www.googleapis.com/auth/plus.me"; private final static String USERINFO_SCOPE = "https://www.googleapis.com/auth/userinfo.profile"; private final static String EMAIL_SCOPE = "https://www.googleapis.com/auth/userinfo.email"; private final static String SCOPES = G_PLUS_SCOPE + " " + USERINFO_SCOPE + " " + EMAIL_SCOPE; 


Register our application.


Originally forgot this item - correct.
We need to go to code.google.com/apis/console to create a project there, go to Credentials and create a new OAuth Client ID by selecting Installed Application -> Android. There we need to enter the name of our package and the SHA1 amount of our key.
With this, I actually had a lot of problems solved in quite a crutch way.
I found debug.keystore in% USERPROFILE% \. Android \ debug.keystore placed it in the project folder and put it in build.grandle:

  signingConfigs { debug { storeFile file("debug.keystore") } myConfig { storeFile file("debug.keystore") storePassword "android" keyAlias "androiddebugkey" keyPassword "android" } } 

Then we need to execute the command:
keytool -exportcert -alias androiddebugkey -keystore ~ ​​/ .android / debug.keystore -v -list
The keytool itself can be found in the SDK. From the output we copy SHA1 into the required field.
As I understand the method is temporary, and for normal operation, you need to create a normal key. But for testing this is enough.

Token receipt code


 protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) { if (requestCode == 123 && resultCode == RESULT_OK) { final String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME); AsyncTask<Void, Void, String> getToken = new AsyncTask<Void, Void, String>() { @Override protected String doInBackground(Void... params) { try { String token = GoogleAuthUtil.getToken(AcrivityName.this, accountName, SCOPES); return token; } catch (UserRecoverableAuthException userAuthEx) { startActivityForResult(userAuthEx.getIntent(), 123); } catch (IOException ioEx) { Log.d(TAG, "IOException"); } catch (GoogleAuthException fatalAuthEx) { Log.d(TAG, "Fatal Authorization Exception" + fatalAuthEx.getLocalizedMessage()); } return token; } @Override protected void onPostExecute(String token) { reg(token); } }; getToken.execute(null, null, null); } } 

Where 123 is your code you entered earlier, where AcrivityName is the name of your activitiv. Roughly speaking - we feed the functions of obtaining a token, the necessary permissions and the name of the account. And note - this all happens in the background, after which the resulting token is transferred to the reg function I wrote. She already sends the token and all the necessary data to the server.
Since I am developing it recently, with exceptions, it’s still a problem, if you have a suggestion - write in a personal or in a comment.

Check the token on the server. (Php)


I want to pay attention, the token received by us has type Online. And it works only 10 minutes. To get an offline token (to work with it longer from the server), refer to this instructions. Developers.google.com/accounts/docs/CrossClientAuth
 $mToken = $_POST['plusToken']; $userinfo = 'https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token=' . $mToken; $json = file_get_contents($userinfo); $userInfoArray = json_decode($json,true); $googleEmail = $userInfoArray['email']; $tokenUserId = $userInfoArray['user_id']; 

Actually we feed the token to googleapis and pick up the received JSON response.

Conclusion


Perhaps the code is raw and written quite crookedly. However, I killed a whole week to find a working solution. I found this solution here: android-developers.blogspot.ru/2012/09/google-play-services-and-oauth-identity.html , although it was not fully operational, much has been added to this article.
Suggestions for improving the article is ready to be heard in a personal or in the comments. I hope to save some time for beginners.

Source: https://habr.com/ru/post/229039/


All Articles