3

I am trying to get google plus authentication working for a web app, but continually get redirect_uri_mismatch errors. I have checked and re-checked that I have matching redirect urls in the code and in the google dev settings.

I have flagged the location that things are breaking at -> ** CRASHES HERE

Any help would be appreciated.

js binding

window.gplusSigninCallback = function(authResult) {
  if (!authResult.code) {
    return;
  }

  request
    .post('/api/users')
    .send({ code: authResult.code })
    .end(function(err, res) {
      dom('#signinButton').remove();
    });
};

google+ component

<span id="signinButton">
  <span class="g-signin"
    data-scope="https://www.googleapis.com/auth/plus.login"
    data-clientid="{clientId}"
    data-redirecturi="postmessage"
    data-accesstype="offline"
    data-cookiepolicy="single_host_origin"
    data-callback="gplusSigninCallback">
  </span>
</span>

POST /users

used code from https://github.com/google/google-api-nodejs-client/blob/master/examples/oauth2.js

'use strict';

const router    = require('express').Router();
const User      = require('../models/user');

const GoogleCreds   = require('../config/google_api_credentials').web;
const googleapis    = require('googleapis');
const OAuth2Client  = googleapis.OAuth2Client;

module.exports = router;

/**
 *
 */
router.post('/', function(req, res) {
  /* jshint camelcase:false  */

  const clientId      = GoogleCreds.client_id;
  const clientSecret  = GoogleCreds.client_secret;
  const redirectUrl   = 'http://localhost:3000';
  const oneTimeCode   = req.body.code;

  try {
    authenticate();
  } catch (ex) {
    console.log(ex.message);
  }

  function authenticate() {
    googleapis
      .discover('plus', 'v1')
      .execute(function(err, client) {
        let oauth2Client = new OAuth2Client(clientId, clientSecret, redirectUrl);

        getAccessToken(oauth2Client, function() {
          getUserProfile(client, oauth2Client, 'me', function(err, profile) {
            if (err) {
              throw new Error(err);
            }

            let userAttrs = {
              foo: 'bar'
            };

            User.findOrCreate(userAttrs, function(err, user) {
              res.set('X-API-TOKEN', user.apiToken);
              res.send(user);
            });
          });
        });
      });
  }

  function getUserProfile(client, authClient, userId, callback) {
    client
      .plus.people.get({ userId: userId })
      .withAuthClient(authClient)
      .execute(callback);
  }

  function getAccessToken(oauth2Client, callback) {
    oauth2Client.generateAuthUrl({
      access_type: 'offline', // will return a refresh token
      scope: 'https://www.googleapis.com/auth/plus.login'
    });

    oauth2Client.getToken(oneTimeCode, function(err, tokens) {
      if (err) {
        // ** CRASHES HERE
        throw new Error(err);
      }
      oauth2Client.setCredentials(tokens);
      callback();
    });
  }
});
chris
  • 4,332
  • 5
  • 41
  • 61
  • These appear to be some good possible solutions: http://stackoverflow.com/questions/13221978/getting-error-redirect-uri-mismatch-the-redirect-uri-in-the-request-http-loc – user3590396 May 04 '14 at 02:41

1 Answers1

6

The reason for the issue was that the redirectUrl on the server side also needs to be set to postmessage.

chris
  • 4,332
  • 5
  • 41
  • 61
  • The "funny" thing is if you use the js API to get the temporary token (not the login button, just gapi.auth.signIn), then setting the client side redirect uri is completely hidden. So i just spent about 4 hours trying to figure why i kept getting the redirect_uri_mismatch error. Big thanks to you. – Kicsi Jun 05 '14 at 09:01