Skip to content

Instantly share code, notes, and snippets.

@Alexandre-Herve
Last active January 9, 2016 09:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Alexandre-Herve/82f22cfd9602636ac4ea to your computer and use it in GitHub Desktop.
Save Alexandre-Herve/82f22cfd9602636ac4ea to your computer and use it in GitHub Desktop.
Custom client redirection after social authentication using passport, koa and koa-router
/**
* This is how I configure koa-router
* with passport to redirect the user
* to exactly where they were in the
* application after a successful
* social authentification.
*/
// store client-provided redirection url
// in session cookie to retrieve it later.
// the user must pass a callback parameter
// to his request, containing the uri-
// encoded location they come from.
function* setCallbackUrlInSession(next) {
if (this.request.query && this.request.query.callback) {
this.session.callback = this.request.query.callback;
}
yield next;
}
// when the user comes back with their token
// after successful login, authenticate and
// then redirect them to the location they
// were at originately.
function getCallbackHandler(socialNetwork) {
return function* (next) {
var ctx = this;
const { callback } = this.session;
const appended = callback ? decodeURIComponent(callback) : '';
yield* passport.authenticate(socialNetwork, function*(err, user, info) {
if (err) throw err
if (user === false) {
ctx.status = 401
ctx.body = { success: false }
} else {
yield ctx.login(user)
ctx.body = { success: true }
}
ctx.response.redirect(successRedirect + `${appended}`);
}).call(this, next);
}
}
// koa-router configuration
router.get('/auth/facebook', setCallbackUrlInSession, passport.authenticate('facebook'));
router.get('/auth/facebook/callback', getCallbackHandler('facebook'));
@wmertens
Copy link

wmertens commented Jan 9, 2016

Hi, I am learning generators and I'm intrigued about how the yield* passport.authenticate(socialNetwork, function*(err, user, info) { works. Is that a wrapped passport that takes a generator or does yield* fn(arg, genfn*) provide the proper context to run the genfn to completion?

Also, why don't you store the uri-decoded callback in the session?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment