Skip to content

Unable to exchange code for access_token on server side #7

Open
@teq

Description

@teq

I am trying to authenticate user on server side (node.js based REST API) as it described here: https://github.com/oauth-io/sdk-node#auth-method, section 'Authenticating the user from the frontend JS SDK'.

Client side (Phonegap oauth.io SDK) works OK and returns code after successful authentication.

Server side code:

  // Called before auth from client
  oauthioStateToken: function(req, res, next) {
    res.json({
      // Our API does not use session, I pass empty object here for now.
      token: oauthio.generateStateToken({})
    });
  },

  // Called after auth from client
  google: function(req, res, next) {
    if (!req.body || !req.body.code) {
      return next(new BadRequestError('No Google access code found'));
    }
    // Again, empty object instead of session for now.
    // This call fails with Error: State is missing from response
    oauthio.auth('google_plus', {} , { code: req.body.code })
    .then(function(reqObject) {
      return reqObject.get("/me");
    })
    .then(function(info) {
      res.json(info);
    })
    .fail(next);
  },

Trying to track down a problem I found this code (oauth.is node.js SDK, file lib/authentication.js):

    authenticate: function(code, session) {
      var defer;
      defer = Q.defer();
      request.post({
        url: cache.oauthd_url + cache.oauthd_base + '/access_token', // https://oauth.io/auth/access_token
        form: {
          code: code, // code, received from client
          key: cache.public_key, // public key from oauth.io. I checked, it matches with client one
          secret: cache.secret_key
        }
      }, function(e, r, body) {
        // Body is {"status":"fail","data":{"code":"invalid or expired"}}
        // Seems like `response.status=="fail"` is unhandled and it falls to
        // "Error State is missing from response" (see below).
        var response, _ref;
        if (e) {
          defer.reject(e);
          return;
        }
        try {
          response = JSON.parse(body);
        } catch (_error) {
          e = _error;
          defer.reject(new Error('OAuth.io response could not be parsed'));
          return;
        }
        if ((response.status != null) && response.status === 'error' && (response.message != null)) {
          defer.reject(new Error('OAuth.io / oauthd responded with : ' + response.message));
        }
        if (response.state == null) {
          defer.reject(new Error('State is missing from response'));
          return;
        }
        if (((session != null ? session.csrf_tokens : void 0) == null) || (_ref = response.state, __indexOf.call(session.csrf_tokens, _ref) < 0)) {
          defer.reject(new Error('State is not matching'));
        }
        if (response.expires_in) {
          response.expires = new Date().getTime() + response.expires_in * 1000;
        }
        response = a.construct_request_object(response);
        if ((session != null)) {
          session.oauth = session.oauth || {};
          session.oauth[response.provider] = response;
        }
        return defer.resolve(response);
      });
      return defer.promise;
    }

I double checked all settings. Public/Secret keys matching. Added localhost and * to domains whitelist (I am testing from localhost). Maybe I messed something important?
Thank you!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions