If you use Identity Toolkit for sign-in and your backend makes your users' data available through an API that requires user authorization, you can securely access your API by using the Secure Token service to exchange a user's ID token for an access token, and then including the access token in your API call. Your API backend can use the access token to verify that the user authorized the API call.
To securely access user data through an authorized API:
Sign in the user using Identity Toolkit. See the developer guides for Android, iOS, and websites.
Get the ID token for the signed-in user.
- On Android, the ID token is a parameter of the
onSignIn
callback that you implement. - On iOS, the ID token is a parameter of the
didFinishSignInWithToken
callback that you implement. - On websites, the ID token is returned to your sign-in success endpoint as
a cookie called
gtoken
.
- On Android, the ID token is a parameter of the
Exchange the ID token for a refresh token using the Secure Token API.
POST /v1/token HTTP/1.1 Host: securetoken.googleapis.com Content-Type: application/x-www-form-urlencoded code=id_token&grant_type=authorization_code
The Secure Token service validates the ID token and returns an access token, a refresh token, and the time left before the access token expires. For example:
{ "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3Mi", "expires_in": "3600", "token_type": "Bearer", "refresh_token": "4sa7yaofbfotcannciLadttp", }
Store the access token, refresh token, and expiration time in your app's local storage.
Whenever you call an API that requires authorization, check if you have an access token or if the access token has expired; if you don't have a valid access token, exchange the refresh token for a new access token using the Secure Token API.
POST /v1/token HTTP/1.1 Host: securetoken.googleapis.com Content-Type: application/x-www-form-urlencoded refresh_token=refresh_token&grant_type=refresh_token
The Secure Token service validates the refresh token and once again returns an access token, a refresh token. and the time left before the access token expires. Store these values on your app's backend if it uses one.
Call the API that requires authorization with the access token. For example:
GET /example_endpoint HTTP/1.1 Authorization: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3Mi Host: apis.example.com
On your API's backend server, decode the access token, verify its integrity, and get the user's ID; then return the requested data.
An access token, when decoded, is a JSON object like the following:
{ "iss": "https://securetoken.google.com", "sub": "user_id" "aud": "project_id", "iat": issued_at, "exp": seconds_to_expiration, "email": "user_email" }
You can use any JWT library to decode the access token and verify some of its claims.
To verify the token, you must verify its signature, and then confirm that the
iss
claim ishttps://securetoken.google.com
, that theaud
claim is your project's Developers Console ID, and that the token hasn't expired.For example, in Python, using Flask and PyJWT:
@app.route("/example_endpoint") def example_endpoint(): access_token = flask.headers["Authorization"] try: user_data = jwt.decode(access_token, issuer="https://securetoken.google.com", audience="exemplary-example-123456") except jwt.InvalidTokenError: return 401 # Invalid token except jwt.ExpiredSignatureError: return 401 # Token has expired except jwt.InvalidIssuerError: return 401 # Token is not issued by Google except jwt.InvalidAudienceError: return 401 # Token is not valid for this endpoint user_id = user_data["sub"] data = get_some_data_by_user_id(user_id) return json.dumps(data)
If the access token is valid, use the value of the
sub
claim to look up and return the requested data.