Server-side authentication using Google accounts in a Chrome extension
Asked Answered
L

2

13

I have a Web application that currently uses OAuth2 to authenticate users using their Google accounts. The flow is quite standard: the user logs in to Google, the web app gets a callback, retrieves the user identity and stores it in the session.

Now I need to create an accompanying Chrome extension. This extension needs to access the web app underneath, so it needs to authenticate against this app. I configured my extension using the official documentation, but during experiments, I realized this is not what I need. Since it uses the OAuth2 implicit flow, it doesn't return a token that could be validated on the server side. This flow is suitable only for using Google APIs on the client side, which is not my use case. This documentation (and pretty much everything else I found on the Web) focuses on two possible cases:

  1. We want to access Google APIs on the extension side (chrome.identity.getAuthToken()).
  2. We want to authenticate using an alternative OAuth2 service (chrome.identity.launchWebAuthFlow()).

However, in my case, I'd like to authenticate users using Google accounts, but process the token on the server side of my Web app. I could use option 2 here, but it just doesn't "feel right" to me to create my own "non-Google authentication service" that is just a wrapper over Google authentication service, only to be able to authenticate on the server side.

Is option 2 really the only way to go, or is there any simpler way?

I also saw someone recommending using the tokeninfo endpoint to validate the token, but I find it hard to make sure that this is indeed an "official" and secure way of doing this.

Longfellow answered 25/5, 2018 at 20:6 Comment(0)
V
0

To retrieve an access token that you can use on both parts of your app, the extension and the server, you should request a Google Cross-Client Access Token. This allows you to register your two apps (two client IDs) in a single project and share an access token.

This is described and discussed by Google here:

The rough steps are:

  1. You will need two clientIds, one for your extension and another for your server app
  2. Add both clientIds to a single project
  3. Retrieve the cross-client access token from your extension
  4. Send it to your server via HTTPS

To do this in Chrome, it looks like you would call chrome.identity.getAuthToken() with a callback function that sends the token to your web app.

The reference says the following on chrome.identity.getAuthToken():

chrome.identity.getAuthToken(object details, function callback)

Gets an OAuth2 access token using the client ID and scopes specified in the oauth2 section of manifest.json.

and that it can take a callback function as specified as:

Called with an OAuth2 access token as specified by the manifest, or undefined if there was an error.

If you specify the callback parameter, it should be a function that looks like this:

function(string token) {...};

Veld answered 2/6, 2018 at 16:40 Comment(1)
I just have the same problem and was thinking in this same solutino, thanks Grokify for pointing me into the Cross-Client documentationRayraya
N
0

I fixed this issue in my project here are the steps

step 1 create 2 OAuth 2.0 Client IDs one for the Chrome extension and one for the web app image1

step 2 add them to code

  • extension manifest.json image2
  • (I create a web app using Golang) image3

step3 get auth token using var token = await chrome.identity.getAuthToken({ interactive: true }); in chrome extension and send it to web app using API

here is the Golang code how to create a client using that token we sent from extension

func Login(c *gin.Context) {
form := LoginDto{}
    if err := c.ShouldBindJSON(&form); err != nil {
        c.String(http.StatusBadRequest, "Missing code google token")
        return
    }
    fmt.Println(form)
    //make client
    token, err := common.GetOauthConfig().TokenSource(c, &oauth2.Token{AccessToken: form.GoogleToken}).Token()
    if err != nil {
        c.String(http.StatusInternalServerError, fmt.Sprintf("Error token: %s", err))
        return
    }
    client := common.GetOauthConfig().Client(c, token)

//other logics
}

NOTE:use same scopes both clients

Nolannolana answered 26/9, 2023 at 17:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.