Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Help setting up the Drupal side for it to work #1

Open
ziaaddils opened this Issue · 7 comments

2 participants

ziaaddils Victor Kareh
ziaaddils

Hello,

I was very happy to see a passport-drupal strategy. I am currently trying to authenticate users of my app with my existing drupal website.

I was not using oauth at all on my drupal website. I installed the OAuth Login Provider module but i'm not getting very far after that.

Could you explain how to setup drupal so that the passport-drupal cant talk to it properly?

I tried playing around creating resources and i did manage to create the consumer key and consumer secret but i access myNodeApp.com:3000/auth/drupal .. i get:

failed to obtain request token
 at /home/ziaaddils/sites/node_sites/newapp/node_modules/passport-drupal/node_modules/passport-oauth/lib/passport-oauth/strategies/oauth.js:196:36
...
...

opening the drupal website: myDrupalWebsite.com/oauth/request_token , i get (in chrome developer tools - network)

request_token
/oauth

Method: get
Status: 401 Unauthorized: No OAuth context found

ps. tried google search but not much out there on services.

Victor Kareh

I have to say, setting up Drupal as an OAuth provider is a real pain. This is how I've done it in the past for Drupal 6 (hopefully some of this will translate into D7 - let me know)

  • Install the following modules:
    • oauth_common (bundled with the OAuth module)
    • oauth_common_providerui (bundled with the OAuth module)
    • oauthloginprovider
    • services
    • services_oauth (bundled with the Services module)
    • rest_server (bundled with the Services module)
    • autoload
  • Go to admin/settings/oauth and check the box Enable the oauth provider
  • On that same page, click on Add Context. Here's the context options:
    • Context name: oauthlogin
    • Context title: This can be whatever - users will see this
    • Signature methods (I don't know if these are all necessary, but this works for me):
      • HMAC-SHA1
      • HMAC-SHA256
      • HMAC-SHA384
      • HMAC-SHA512
    • Authorization options (these are mostly user-visible stuff):
      • Access token lifetime: 0 (this makes it permanent, change to suit your needs)
      • Check on Disable authorization level selection (I never figured out how to use the auth level selections, so I disabled it)
    • Authorization levels (I only have one):
      • Name: user_info
      • Check on Selected by default
  • Go to admin/build/services and there should be an endpoint called oauthlogin, click on Edit:
    • Name: oauthlogin
    • Server: REST
    • Path to endpoint: oauthlogin/api
    • Check on Apply content permissions (I think this might be optional)
    • Check on OAuth authentication
  • Go to admin/build/services/list/oauthlogin/resources and check on oauthlogin. Set alias to user.
  • Go to admin/build/services/list/oauthlogin/server:
    • Response formatters: Check only JSON - uncheck everything else
    • Request parsing: Check everything
  • Go to admin/build/services/list/oauthlogin/authentication and make sure that the context you created initially is selected (should be the only one, I think)
  • Now this is the really weird part... Go to user/1/oauth (yes, user 1) and click on Add Consumer
    • Consumer name: whatever you want (users won't see this)
    • Callback url: http://localhost:3000/auth/drupal/callback (or whatever URL points to your node.js app) - the auth/drupal/callback is hard-coded into the passport-drupal module
    • Save this and go back and edit it to get access to your key/secret pairs. These are the ones you should enter into your passport.json file:
{
    "drupal" : {
        "requestTokenURL": "http://drupal.example.com/oauth/request_token",
        "accessTokenURL": "http://drupal.example.com/oauth/access_token",
        "userAuthorizationURL": "http://drupal.example.com/oauth/authorize",
        "consumerKey": "KEY FROM PREVIOUS STEP",
        "consumerSecret": "SECRET FROM PREVIOUS STEP",
        "callbackURL": "http://localhost:3000/auth/drupal/callback",
        "resourceURL": "http://drupal.example.com/oauthlogin/api/user/info"
    }
}

Phew! Hope this works for you - if it does, let me know as it would be good to document this.

Victor Kareh

Forgot to mention that the Consumer list under user-1 will actually authenticate any user with their own credentials (no need to worry about extra permissions) - so that's part of the weirdness.

You can also add multiple consumers for different apps (node.js or otherwise). This allows you to have different tokens in your development and production servers

ziaaddils

Hi thanks for the very detailed answer. Helped me tons.

I managed to get the dance going (like they say). only thing is when the callback is fired

app.get('/auth/drupal/callback', 
  passport.authenticate('drupal', { failureRedirect: '/login' }),
  function(req, res) {
    // Successful authentication, redirect home.
    res.redirect('/');
  });

on the browser i'm getting

[object Object]

instead of showing me the authenticated page . very weird.

any idea on this?

Victor Kareh

That is very weird - never seen anything like that. It seems like something is going on in the req variable of your root / router. Passport sets the user profile object in req.user, so maybe this is interfering with the correct routing of /?

Also, you can try checking for req.authenticated === true or req.isAuthenticated() === true.

ziaaddils

From the code below... seems like the error occurs in the passport.authenticate part because i am not getting the console.log in the successful authentication part.

I am a bit lost actually.. googling a bit

app.get('/auth/drupal/callback', 
  passport.authenticate('drupal', { failureRedirect: '/login' }),
  function(req, res) {
    // Successful authentication, redirect home.
    console.log('im authenticated on drupal'); // this is never displayed
    res.redirect('/');
  }
);
Victor Kareh

I've tried many things and still can't replicate your issue - can you paste your entire express middleware code (or at least all parts relevant to passport). If this doesn't work, it might be a weird Drupal-specific configuration that's preventing this from working, although it seems like Drupal is redirecting properly back to the callback URL?

Also, a few days ago I ran into a problem when authenticating two different node.js apps against the same Drupal instance. The node.js app were both being routed through nginx on the same server, and due to the way the server was configured (specifically the proxy_set_header) it was failing on one of the apps - took me a while to get the right nginx configuration. This might not be your same issue, but I mention it just in case it helps debug.

On a side note, you might want to add the following to your code authorization callback, right before the res.redirect():

app.get('/auth/drupal/callback', 
  passport.authenticate('drupal', { failureRedirect: '/login' }),
  function(req, res) {
    // Move the oauth credentials into the session proper, not the
    // user record. This means we can push the user record to the
    // client without leaking secrets.
    req.session.oauth = req.user.oauth;
    delete req.user.oauth;

    // Depending on your application, you might also want to store
    // the user object into the session for retrieval after the redirect
    req.session.user = req.user;

    // Successful authentication, redirect home.
    res.redirect('/');
  }
);
Victor Kareh

I've created a gist with an express middleware example for passport-drupal: https://gist.github.com/vkareh/5918536

Hope this helps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.