Oauth2 flow without redirect_uri
Asked Answered
F

5

10

I am creating an Android/iOS app which communicates with a Node.js server and would like to identify them securely on my server using Google (and/or Facebook) and OAuth2. I've looked at the following documentation: https://developers.google.com/+/web/signin/server-side-flow

I do not need authorization, I only need authentication (I only want to make sure that the person calling my Node.js service is the person they say they are). To achieve this, if I understand properly, I have to let the user log in using Google on the client side, this will give them an authorization_code which they can then give to my server. My server can then exchange that code for an access_token, and therefore retrieve information about the user. I am then guaranteed that the user is the person they say they are.

The Google documentations (link above) says: "In the Authorized redirect URI field, delete the default value. It is not used for this case.", however, for my server to exchange the authorization_code for an access_token, it needs to provide a redirect_uri, am I missing something?

The redirect_uri is useless for Unity games, for instance (since logging in with Google simply opens a new "window", which is closed when logged in, no redirection involved).

TL;DR How do you use OAuth2 to authenticate users between my client and my server without redirection?

Fork answered 17/12, 2014 at 22:39 Comment(0)
F
6

TL;DR How do you use OAuth2 to authenticate users between my client and my server without redirection?

You can't. OAuth requires that the user is directed to an authorization (and possibly login) screen, and then redirected back to your app.

EDIT 20/12/22. See comment below regarding latest status

Finis answered 18/12, 2014 at 15:34 Comment(4)
I've seen somewhere in Google's documentation that they use 'postmessage' redirect_uri, but I can't find out if that's the problem they're trying to circumvent.Fork
I chose this as the answer, however I would like to mention that using 'postmessage' worked perfectly for my purposes, but that is not part of the "normal" OAuth2 flow, it's a workaround implemented by Google. There isn't much documentation about it, but I found out about it here: developers.google.com/+/web/signin/…Fork
@Fork : the link gives a 404Range
This isn't true as of the current Authentication and Authorization APIs - they support both redirect and popup flows as well as the new One Tap system: developers.google.com/identity/one-tap/android/…Uniliteral
I
5

Have you looked at this documentation? https://developers.google.com/accounts/docs/OAuth2InstalledApp#choosingredirecturi

Choosing a redirect URI

When you create a client ID in the Google Developers Console, two redirect_uris are created for you: urn:ietf:wg:oauth:2.0:oob and http://localhost. The value your application uses determines how the authorization code is returned to your application.

http://localhost

This value signals to the Google Authorization Server that the authorization code should be returned as a query string parameter to the web server on the client. You may specify a port number without changing the Google Developers Console configuration. To receive the authorization code using this URL, your application must be listening on the local web server. This is possible on many, but not all, platforms. If your platform supports it, this is the recommended mechanism for obtaining the authorization code.

Inadmissible answered 17/12, 2014 at 22:57 Comment(1)
I have, but the issue is that those are "callbacks". This doesn't really make sense on a native application, or from a unity application for instance because there isn't a webpage, nor a webserver.Fork
S
3

I had this problem and it took me ages to find the "postmessage" solution that Nepoxx mentions in the comments of the accepted answer here.

For clarification, here's what worked for me.

  1. Follow steps 1-6 here: https://developers.google.com/identity/sign-in/web/server-side-flow
  2. Install googleapis library npm install --save googleapis
  3. For the server-side token exchange do this:
    var googleapis = require('googleapis');
    var OAuth2 = googleapis.auth.OAuth2;

    var oauth2Client = new OAuth2(
       GOOGLE_SSO_CLIENT_ID,
       GOOGLE_SSO_CLIENT_SECRET,
       'postmessage' // this is where you might otherwise specifiy a redirect_uri
    );

    oauth2Client.getToken(CODE_FROM_STEP_5_OF_INSTRUCTIONS, function(err, tokens) {
       // Now tokens contains an access_token and an optional refresh_token. Save them.
    });
Shaver answered 31/5, 2017 at 10:0 Comment(1)
Blimey this workaround took me an hour to find! I can confirm it also works with the latest authorization code model workflow developers.google.com/identity/oauth2/web/guides/use-code-modelUniliteral
A
2

The redirect_uri can be a URL with a custom URL scheme for which the client registered a handler. This is described here: What's a redirect URI? how does it apply to iOS app for OAuth2.0?. It is not so much about "redirecting" it is about a callback endpoint to your app.

Af answered 7/1, 2015 at 18:58 Comment(0)
C
1

And it become really easy if you use VueJS with https://github.com/guruahn/vue-google-oauth2

Client side

import GAuth from 'vue-google-oauth2'

Vue.use(GAuth, {
    clientId: 'xxxxxxx.apps.googleusercontent.com',
    scope: 'profile',
})
async signWithGoogle() {
    const code = await this.$gAuth.getAuthCode() //
    console.log(code ) // { code: 'x/xxxxxxxxxx' }
    // send the code to your auth server
    // and retrieve a JWT or something to keep in localstorage
    // to send on every request and compare with database
}

Server side

import { google } from 'googleapis'

const oauth2Client = new google.auth.OAuth2(GOOGLE_ID, GOOGLE_SECRET, 'postmessage')

google.options({ auth: oauth2Client })

async function getAccount(code) {
    // the code you sent with the client
    const { tokens } = await oauth2Client.getToken(code)
    oauth2Client.setCredentials(tokens)
    const oauth2 = google.oauth2({ version: 'v2' })
    const { data: { id } } = await oauth2.userinfo.get()
    // there you have the id of the user to store it in the database
    // and send it back in a JWT
}
Corpulence answered 18/4, 2019 at 15:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.