Question

I have an app which uses nodejs but I don't serve my pages via ExpressJS. It is a simple http nodejs app which I will migrate to nodejs at some stage.

However, I am playing around with Passportjs and currently I am getting 'passport.intitalize() middleware not in use' errors which from the documentation mention 'connect' and 'Express' usage.

Can I use passportjs without Expressjs?

Was it helpful?

Solution 2

Short version: No, express is required for regular passport usage.

Long version: You could technically use a large portion of passport's code in a non-express application, but that could create all sorts of edge cases you don't want in your auth code. It'd also probably be easier just to convert your application to express.

OTHER TIPS

Passport Strategies expect inputs on certain channels (e.g. 'Local' looks for username and password fields on <OBJ>.body), but if you provide for these Strategy requirements directly you can use Passport just fine without Express/Connect.

Take a look directly at comments lifted from the relevant Passport code:

https://github.com/jaredhanson/passport/blob/master/lib/authenticator.js#L146

passport.authenticate('local', function(err, user) {
  if (!user) { return res.redirect('/login'); }
  res.end('Authenticated!');
})(req, res);

If you provide req and res as your own objects (paying attention to the requirements of the Strategy you're using and whatever you're using of req/res in authenticate), you have total control.

(Or just write a simple custom framework wrapper).

take an example for oauth2 without express, besides papercowboy's local example:

const i_url = require('url');
const i_crypto = require('crypto');
const i_jwtDecode = require('jwt-decode');
const i_passport = require('passport');
const i_OAuth2Strategy = require('passport-oauth2').Strategy;

const AUTH_SSO_AUTH_URL = process.env.SSO_AUTH_URL;
const AUTH_SSO_TOKEN_URL = process.env.SSO_TOKEN_URL;
const AUTH_SSO_CLIENT_ID = process.env.SSO_CLIENT_ID;
const AUTH_SSO_SECRET = process.env.SSO_SECRET;
const AUTH_SSO_CB_URL = process.env.SSO_CB_URL;


i_passport.use(new i_OAuth2Strategy({
   authorizationURL: AUTH_SSO_AUTH_URL,
   tokenURL: AUTH_SSO_TOKEN_URL,
   clientID: AUTH_SSO_CLIENT_ID,
   clientSecret: AUTH_SSO_SECRET,
   callbackURL: AUTH_SSO_CB_URL,
}, (accessToken, refreshToken, params, profile, cbFn) => {
   if (!params.id_token) return cbFn(new Error('invalid user'), null);
   const tokenObj = i_jwtDecode(params.id_token);
   if (!tokenObj.sub) return cbFn(new Error('invalid user name'), null);
   const username = tokenObj.sub.split('@')[0];
   const userObj = { username, refreshToken };
   return cbFn(null, userObj);
}));
i_passport.initialize();

const api = {
   login: async (req, res) => {
      // simulate express body-parser
      const query = {};
      i_url.parse(req.url).query.split('&').forEach((kv) => {
         const parts = kv.split('=');
         const k = decodeURIComponent(parts[0]);
         const v = decodeURIComponent(parts[1] || '');
         query[k] = v;
      });
      req.query = query;
      const cookie = {};
      req.headers.cookie.split('; ').forEach((kv) => {
         const parts = kv.trim().split('=');
         const k = decodeURIComponent(parts[0]);
         const v = decodeURIComponent(parts[1] || '');
         query[k] = v;
      });
      req.cookies = cookie;

      i_passport.authenticate('oauth2', (err, user, info) => {
         try {
            if (err) return makeRedirect(res, '/login.html?error=400');
            if (!user) return makeRedirect(res, '/login.html?error=401');
            // TODO: the user logged in. res.end(user.username);
         } catch(err) {
            console.error(err);
         }
         return makeRedirect(res, '/login.html?error=500');
      })(req, res);
   }
};
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top