Menu Search Me

Google Apps

Created by JimmyXu on 2020-12-24

Manually build a login flow with Google OAuth

Here is the use case: when a user comes to app X, app X wants to give the user the possibility of logging into app X via google; app X also wants to collect the user's email and other info from google. App X does not want to use google's javascript SDK.

High level implementation:

  1. When a user chooses to login via google, App X browser side redirects the user to a google oauth /auth endpoint, specifying app X's client_id, redirect_uri, and a dynamically generated "state" value. You can also specify a space delimited scope for what permissions you need. You should also include the following parameters with the values in brackets: response_type (code), access_type (offline) include_granted_scopes (true).
  2. User gets onto Google login page, logs into google (if not already), enables permissions he wants to give to app X.
  3. Google redirects the user back to app X's redirect URL, with the "state" parameter and a code parameter.
  4. App X verifies the "state" parameter, sends the code to its server side.
  5. The server side of App X takes the code, and sends an HTTP POST request to google oauth2 end point oauth2.googleapis.com/token, including code passed from its client side, client_id, client_secret, the same redirect_uri used on its client side, and grant_type (authorization_code)
  6. Google Oauth will return the requested access token (which you can use right away to access other google API), a refresh token (which is always valid until user decides not to grant App X the permissions anymore, and which App X can use to get a refreshed access token), and expires_in (which indicates the life time of the returned access token).
  7. App X can start to use the access token to call a google API to get the user's email or other information.

Below is an example redirect call request (scope is readonly google drive and userinfo email). It is an http get redirect:

https://accounts.google.com/o/oauth2/v2/auth?
 scope= https%3A//www.googleapis.com/auth/drive.readonly%20https%3A//www.googleapis.com/auth/user.profile%20https%3A//www.googleapis.com/auth/userinfo.email &
 access_type=offline&
 include_granted_scopes=true&
 response_type=code&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

Below is an example redirect response if access is denied by the user:

https://oauth2.example.com/auth?error=access_denied

Below is an example redirect response if access is granted by the user:

https://oauth2.example.com/auth?state=853jkw55N41525377401217&code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7

Below is an example exchange of code for access token request:

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your_client_id&
client_secret=your_client_secret&
redirect_uri=https%3A//oauth2.example.com/code&
grant_type=authorization_code

Below is an example exchange of code for access token response:

{
  "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
  "expires_in": 3920,
  "token_type": "Bearer",
  "scope": "https://www.googleapis.com/auth/drive.metadata.readonly",
  "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}

When you need to refresh your access token, below is a sample request:

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

client_id=your_client_id&
client_secret=your_client_secret&
refresh_token=refresh_token&
grant_type=refresh_token

Below is a sample response:

{
  "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
  "expires_in": 3920,
  "scope": "https://www.googleapis.com/auth/drive.metadata.readonly",
  "token_type": "Bearer"
}

Reference: https://developers.google.com/identity/protocols/oauth2/web-server

How to get a user's email

Do the following GET request:

https://www.googleapis.com/oauth2/v1/userinfo?alt=json

With the following http request header:

Authorization": "Bearer <your access token>"

Here is sample response:

{
    "id": "112604589324829722117",
    "name": "Jimmy Tang",
    "email": "smoe@gmail.com",
    "verified_email": true,
    "given_name": "Jimmy",
    "family_name": "Tang",
    "picture": "https://lh4.googleusercontent.com/-1okS7VD0/AAAAAAAAAAI/AAAAAAAAAAA/AMZuuclpuyj2TR7G_b_u0lJVWTlb4SIHQw/s96-c/photo.jpg",
    "locale": "en"
}

How to use Google Drive API

If you are accessing a user?s Google Drive on behalf of the user, these are the permissions you need to get, depending on what you want to do: https://developers.google.com/drive/api/v3/about-auth

For example, to be able to download the user?s files on google drive, you will need to have the https%3A//www.googleapis.com/auth/drive.readonly permission (put it in the scope when you are requesting access token).

Reference the Google Drive API reference document: https://developers.google.com/drive/api/v3/reference/files/list