简体   繁体   English

Passport.js可选身份验证

[英]Passport.js optional authentication

Is there an optional authentication middleware from Passport.js? Passport.js是否有可选的身份验证中间件?

Let's say I have a route, /api/users . 假设我有一条路线, /api/users I want to give just a list of users to the public, but to authenticated people, I want to add more fields. 我想向公众提供一个用户列表,但对于经过身份验证的人员,我想添加更多字段。

Currently I have just a dumb custom method that does the same thing, but I wonder if: 目前我只有一个愚蠢的自定义方法做同样的事情,但我想知道:

  • Passport.js already provides such thing or Passport.js已经提供了这样的东西或
  • how can I make this a part of passport, like a plugin or so. 我怎样才能使这成为护照的一部分 ,就像插件一样。

My method, roughly, looks like 粗略地说,我的方法看起来像

function optionalAuth(req, res, next) {

    var authHeader = req.headers.authorization;
    var token = parseToken(authHeader); // just getting the OAuth token here
    if(!token) {

        return next();
    }
    User.findOne({
        token: token
    }, function(err, user) {

        if(err) {
            return res.json(401, {message: 'auth expired'});
        };
        if(user) {
            req.user = user;
        }
        next();
    });
}

This, however, seems dumb to me, and also not in passport-auth-strategies.js or some other auth layer where I think it should be. 然而,这对我来说似乎是愚蠢的,而且在passport-auth-strategies.js或其他我认为应该存在的auth层中也没有。 What is the better way to do it? 有什么更好的方法呢?

Bonus points for telling me if I'm doing the proper thing returning 401 if I find a token but it's invalid :) 奖励点告诉我,如果我找到一个令牌但是它无效,我是否正在做正确的事情返回401

Here's a simple PoC: 这是一个简单的PoC:

var express       = require('express');
var app           = express();
var server        = app.listen(3012);
var passport      = require('passport');
var LocalStrategy = require('passport-local').Strategy;

app.use(passport.initialize());

passport.use(new LocalStrategy(function(username, password, done) {
  if (username === 'foo' && password === 'bar') {
    return done(null, { username : 'foo' });
  }
  return done(null, false);
}));

app.get('/api', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    var data = { hello : 'world' };
    // Only if the user authenticated properly do we include secret data.
    if (user) {
      data.secret = '3133753CR37';
    }
    return res.send(data);
  })(req, res, next);
});

It's calling passport.authenticate 'manually' in the /api endpoint. 它在/api端点中“手动”调用passport.authenticate That way, you get more control over how to deal with authentication error (which—in your situation—shouldn't be treated as errors but as a way of limiting the output). 这样,您可以更好地控制如何处理身份验证错误(在您的情况下 - 不应该将其视为错误,而是作为限制输出的方式)。

Here's the output without proper authentication: 这是没有适当身份验证的输出:

$ curl 'localhost:3012/api?username=foo&password=wrong'
{"hello":"world"}

And here's with: 以下是:

$ curl 'localhost:3012/api?username=foo&password=bar'
{"hello":"world","secret":"3133753CR37"}

To use as a middleware: 要用作中间件:

var middleware = function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    req.authenticated = !! user;
    next();
  })(req, res, next);
};

app.get('/api', middleware, function(req, res, next) {
  var data = { hello : 'world' };
  if (req.authenticated) {
    data.secret = '3133753CR37';
  }
  return res.send(data);
});

Might be late now, but there's an anonymous Passport strategy to allow exactly this. 现在可能会迟到,但是有一个anonymous Passport策略允许这一点。 That way the public routes can either take authentication or not, but when they do you'll still have all of the information associated with the authenticated user. 这样,公共路由可以是否进行身份验证,但是当它们执行时,您仍将拥有与经过身份验证的用户相关联的所有信息。 Check it out here: https://github.com/jaredhanson/passport-anonymous 在这里查看: https//github.com/jaredhanson/passport-anonymous

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM