trailsjs / sails-auth

Passport-based User Authentication system for sails.js applications. Designed to work well with the sails-permissions module.
https://www.npmjs.org/package/sails-auth
MIT License
265 stars 141 forks source link

How to redirect user after passport login? #73

Open slavafomin opened 8 years ago

slavafomin commented 8 years ago

Hello!

I'm using passport login and google provider. After logging in, Sails returns JSON document with profile information. How do I redirect client to the page of my choice instead (e.g. homepage or profile page)?

Thank you.

kulakowka commented 8 years ago

You can use /auth/local?next=/profile for redirect user after sign in or sign up;

For example:

<h1>Login</h1>
<form action="/auth/local?next=/profile" method="post">
    <input type="text" name="identifier" placeholder="username or email">
    <input type="password" name="password" placeholder="password">
    <input type="hidden" name="next" value="/" >
    <button type="submit">login</button>
</form>

Look source for understanding: https://github.com/tjwebb/sails-auth/blob/master/api/controllers/AuthController.js#L118

// Upon successful login, optionally redirect the user if there is a
// `next` query param
if (req.query.next) {
  res.status(302).set('Location', req.query.next);
}

For google auth, use returnURL: 'http://www.example.com/auth/google/return?next=/profile',

For example:

var passport = require('passport')
  , GoogleStrategy = require('passport-google').Strategy;

passport.use(new GoogleStrategy({
    returnURL: 'http://www.example.com/auth/google/return?next=/profile',
    realm: 'http://www.example.com/'
  },
  function(identifier, profile, done) {
    User.findOrCreate({ openId: identifier }, function(err, user) {
      done(err, user);
    });
  }
));

Unfortunately, I am unable to check it out now. But the idea - it should work.

slavafomin commented 8 years ago

Thank you @kulakowka for your response. I've managed to achieve the desired result by editing the config/passport.js file:

var _ = require('lodash');
var _super = require('sails-auth/config/passport');

_.merge(exports, _super);
_.merge(exports, {
  passport: {
    google: {
      options: {
        clientID: '...',
        clientSecret: '...',
        callbackURL: 'http://localhost:1337/auth/google/callback?next=/'
      }
    }
  }
});

However, I have two problems with it:

  1. I don't like that I have to specify an absolute path here, because the domain name (and port) will depend on environment and I don't want to hardcode the domain name.
  2. I have to specify return URL as a part of callback URL for each authentication method. It violates the DRY principle. And also what if I would like to use different return URLs depending on some runtime condition?

Thank you!

kulakowka commented 8 years ago

Maybe you can use callbackURL: http://localhost:1337/auth/google/callback?next=/after_login

Then in action /after_login you can redirect user to the right place.

The endpoint for redirection may be stored in a cookie, for example.

slavafomin commented 8 years ago

That's a smart idea @kulakowka, thanks!

However, I still don't like the idea of overriding the callbackURL for each individual provider. Maybe this idea of using special after-login route could be implemented in the module itself? Then each user will be able to override it and replace with custom redirection logic.

enricodeleo commented 8 years ago

It would be nice to have some configuration like redirect url on login/signup, just like https://github.com/jaumard/sails-hook-passport does.

priyankgandhi commented 7 years ago

Below solution works perfectly fine. callbackURL: '/auth/google/callback?next=/',