express - Auth0 LoopbackJS API access token using 3rd party login -


i have loopbackjs api hosted on domain (e.g. http://backend.com), third party authentication setup via auth0. have front-end hosted spa on domain (e.g. http://frontend.com)

loopback-component-passport seems work fine when front-end on same domain api, , sets userid , access_token cookies accordingly. however, front-end in production on different domain api, example api auth link like:

"http://backend.com/auth/auth0?returnto=" + encodeuricomponent("http://frontend.com")

the backend has used same auth pattern in loopback-passport-example, providers.json file specifies connection details auth0 (although have tried other social providers such facebook).

  "auth0-login": {     "provider": "auth0",     "module": "passport-auth0",     "clientid": "auth0_client_id",     "clientsecret": "auth0_client_secret",     "callbackurl": "/auth/auth0/callback",     "authpath": "/auth/auth0",     "callbackpath": "/auth/auth0/callback",     "successredirect": "/",     "failureredirect": "/login",     "scope": ["email"],     "failureflash": true   } 

the front-end (http://frontend.com) has link on page redirect api authentication:

<a href="http://backend.com/auth/auth0">login</a> 

clicking on link redirects auth0 properly, , can login. redirects specified target (http://backend.com or http://frontend.com, whichever specified). returnto query parameter seems work expected.

is there way capture access_token before redirecting front-end, , somehow communicate (e.g. query parameters, unless insecure).

after more investigation, settled on method use passing access token , userid loopbackjs backend, separate front-end. documented on github pull-request, using customcallback of passport-configurator.

other places have referenced this fork, issue #102, issue #14 , pull request #155.

there 2 options here, either use fork of loopback-component-passport (e.g. 1 referenced above) npm dependency, or provide customcallback passport configuration option documented.

i wanted little more control on format of url, ended customcallback method. in loopback-example-passport, inside /server/server.js there basic code passing providers.json passport configurator:

var config = {}; try {   config = require('../providers.json'); } catch (err) {   console.trace(err);   process.exit(1); // fatal } passportconfigurator.init(); (var s in config) {   var c = config[s];   c.session = c.session !== false;   passportconfigurator.configureprovider(s, c); } 

this can replaced documented customcallback code, passport variable being assigned passportconfigurator.init():

var providers = {}; try {   providers = require('../providers.json'); } catch (err) {   console.trace(err);   process.exit(1); // fatal }  const passport = passportconfigurator.init(); object.keys(providers).foreach(function(strategy) {    var options = providers[strategy];   options.session = options.session !== false;    var successredirect = function(req) {     if (!!req && req.session && req.session.returnto) {       var returnto = req.session.returnto;       delete req.session.returnto;       return returnto;     }     return options.successredirect || '';   };    options.customcallback = !options.redirectwithtoken      ? null      : function (req, res, next) {       var url = require('url');       passport.authenticate(         strategy,         {session: false},         function(err, user, info) {           if (err) {             return next(err);           }            if (!user) {             return res.redirect(options.failureredirect);           }           var redirect = url.parse(successredirect(req), true);            delete redirect.search;            redirect.query = {             'access_token': info.accesstoken.id,             'userid': user.id.tostring()           };           redirect = url.format(redirect);           return res.redirect(redirect);         }       )(req, res, next);   };    passportconfigurator.configureprovider(strategy, options); }); 

in above example, have copied successredirect function used in passport-configurator.js, use same returnto query parameter. option within providers.json can set e.g. "redirectwithtoken": true, results in redirect auth strategies need external redirect.

one more final bit of code in case returnto redirect required. if exists query parameter, should added @ session level:

app.use(function(req, res, next) {   var returnto = req.query.returnto;   if (returnto) {     req.session = req.session || {};     req.session.returnto = require('querystring').unescape(returnto);   }   next(); }); 

now, if backend api @ url such http://api.com, , front-end hosted @ domain e.g. http://gui.com, authentication link can placed on front-end:

<a href="http://api.com/auth/facebook?returnto=http%3a%2f%2fgui.com">login!</a> 

this result in api auth call, redirect returnto link access token , userid in query parameters.

potentially in future, 1 of issues or other pull requests merged provide more ideal method 3rd party domain redirection, until method work well.


Comments

Popular posts from this blog

PySide and Qt Properties: Connecting signals from Python to QML -

c# - DevExpress.Wpf.Grid.InfiniteGridSizeException was unhandled -

scala - 'wrong top statement declaration' when using slick in IntelliJ -