Chrome extension with Google OAuth and Phoenix backend

Hello, I realize this is kind of a mixed-up topics question, but I think I will ask anyway, hopefully I get useful feedbacks :smiley:

This is an architecture question. I have an API service built using Phoenix. Among others, it will handle user registration, but to ease the adoption I’m intending to only open registration using social media accounts (right now only Google, possibly with Facebook in the future); all the OAuth basic stuff and I will save the authenticated user’s name and email to my DB. I am not accessing other Google or other services, only for authentication.

The OAuth authentication process will be initiated by the client, a chrome extension (basically a single page JS app). My question is: how should the client handle this? I have two approaches in mind:

Approach 1: Directly to Google

On clicking the sign-in with Google button, the client will authenticate directly to Google OAuth using the chrome.identity API. It will receive access_token on the redirect url, and it will post the token to the API’s /auth endpoint. The API will then validate using the tokeninfo Google endpoint, and if the token is valid, insert the data from tokeninfo to DB, and then returning Phoenix.Token to client for further requests.

Approach 2: Using Ueberauth

On clicking the sign-in with Google button, the client will open up a new window to a route in my Phoenix app for handling OAuth using Ueberauth. The route will then process all the authentication, callback, inserting to database, generate token and returning the Phoenix.Token back to the extension via message passing. It seems possible, but I haven’t tried it yet.

Any thoughts? Particularly on the security point-of-view. I see approach 2 will help me if I wanted to add Facebook login in the future, but I don’t know if it’s doable or secure. Thanks!

2 Likes

I haven’t used or read about Approach 1, so can’t comment that. However, If I were you, I’d use ueberauth with google oauth. Primarily because familiarity with it and the other reasons (You total control, You can add email/password auth or other auth)

1 Like

Thanks for your reply. I do prefer approach 2 if possible, but I don’t know if it is.

The source of my confusion, I think, is that most documentations and tutorials are either

  1. Server app <–> Google Services, or
  2. Client-side JS app <–> Google Services

Meanwhile what I think approach 2 needed is:

Client-side JS app <–> Server app <–> Google Services

I don’t want this to be an XY problem, so I hope I’ve stated my intention clear enough that someone here might know a better solution :sweat_smile:

1 Like

Struggling with the exact same issue if anyone has found a solution yet :slight_smile:

Hi, @blb451. I’ve solved this using approach 2.

When the user clicked on a sign-in with Google button, the extension’s background will open a new window with a certain URL on our server that initiates OAuth. The server then interact with Ueberauth as normal, and a successful OAuth will call the Ueberauth callback on the server. In the callback, I upsert the user, generate a token, and throw a redirect to a special URL (in my case its <server>/auth/retrieve#<token> with <token> is the generated Phoenix.Token. The content of this special URL page is not important, only the URL is. We also use a hash (#) instead of a query param since we don’t want the token to be stored in the logs. The server flow is done.

On the client, after opening the new window, the background page listens to all tabs’ onUpdated events and check if their URL contains the special retrieve URL. If it’s so, parse the URL to extract the token from the hash, and store it in local storage for further use by the client.

2 Likes

Just curious - which extension did you end up making? Is it open source?

After reading this post, I want to to use Phoneix channels in chrome extension. :stuck_out_tongue: