2014-09-12 2 views
8

Есть ли дополнительное программное обеспечение для проверки подлинности от Passport.js?Дополнительная аутентификация Passport.js

Предположим, у меня есть маршрут, /api/users. Я хочу предоставить список пользователей для публики, но для аутентифицированных людей я хочу добавить больше полей.

В настоящее время я просто тупой пользовательский метод, который делает то же самое, но мне интересно, если:

  • Passport.js уже предоставляет такую ​​вещь или
  • , как я могу сделать это часть из паспорт, как плагин или так.

Мой метод, грубо говоря, выглядит

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(); 
    }); 
} 

Это, однако, кажется стремно мне, а также не в паспортном-AUTH-strategies.js или какой-либо другой слой аутентификации, где я думаю, что он должен быть. Каков лучший способ сделать это?

Бонусных баллов за рассказывал мне, если я делаю правильную вещь, возвращающуюся 401, если я найду фишку, но это недопустимое :)

+0

Предполагая, что у вас есть основы работы (аутентификация пользователей), я думаю, вы можете использовать 'req.isAuthenticated()' (что-то, что определяет Passport), чтобы проверить, хотите ли вы вернуть дополнительный полей или нет. – robertklep

+0

Я не могу использовать req.isAuthenticated, потому что до этого я не могу поместить pass.authenticate(). Зачем? Потому что пользователи, не прошедшие проверку подлинности, будут отклонены. У меня нет сеанса, это API без состояния, только токен-носитель. Если я положу паспорт.authenticate() на маршруте, некоторые пользователи получат 401. Я хочу, чтобы они проходили, только получайте ограниченную информацию. – Zlatko

ответ

9

Вот простой 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); 
}); 

Он звонит passport.authenticate «вручную 'в конечной точке /api. Таким образом, вы получаете больше контроля над тем, как бороться с ошибкой аутентификации (которая в вашей ситуации не должна рассматриваться как ошибки, а как способ ограничения вывода).

Вот вывод без надлежащей аутентификации:

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

А вот с:

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

Для использования в качестве промежуточного слоя:

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); 
}); 
+0

Спасибо. В некотором роде это лучше, чем моя попытка, поскольку она использует паспорт для auth. Но это немного более неуклюжий, я не могу просто назвать его промежуточным программным обеспечением на маршрутах, не прошедших проверку подлинности. Но это может быть обернуто в какой-то плагин. Я должен попробовать. – Zlatko

+0

@Zlatko Я отредактировал свой ответ, чтобы дать представление о том, как вы могли превратить его в промежуточное ПО. – robertklep

+0

Удивительно, все, лучше, чем вмешаться. – Zlatko

6

Может быть поздно, но есть anonymous Стратегия паспорта, позволяющая именно это. Таким образом, общедоступные маршруты могут либо проходить аутентификацию, либо нет, но когда они это сделают, вы все равно будете иметь всю информацию, связанную с аутентифицированным пользователем. Проверьте это здесь: https://github.com/jaredhanson/passport-anonymous

+0

Это уже поздно для этой работы, но может помочь будущим :) – Zlatko

Смежные вопросы