Pergunta

Meu aplicativo usa Express e AngularJS.Estou usando o express para lidar com o serviço básico da web do código angular via estático.O código angular usa serviços que atingem os endpoints da API hospedados pelo Express.Desejo apenas que os endpoints da API sejam acessíveis após a autenticação do usuário.Como posso fazer isso via PassportJS?

Foi útil?

Solução

Eu carreguei um Angular-Express projeto no github em que estou trabalhando.

Ainda está em andamento.Espero que ajude.

Ele usa PassportJs para autenticação de usuário e é um exemplo básico de autorização no servidor.Ele demonstra como tornar as chamadas de API acessíveis apenas para usuários autenticados ou apenas para usuários com função administrativa.Isto é conseguido em server/routes.js chamando as funções de middleware ensureAuthenticated, e ensureAdmin que são definidos em server/authentication.js

em rotas.js

// anybody can access this 
app.get('/api/test/users', 
        api.testUsers);


// only logged-in users with ADMIN role can access this 
app.get('/api/users',          
        authentication.ensureAdmin,
        api.testUsers);

// only logged-in users can access this
app.get('/api/books', 
        authentication.ensureAuthenticated, 
        api.books);

em autenticação.js

ensureAuthenticated: function(req, res, next) {
    if (req.isAuthenticated()) {
       return next();
    } else {
       return res.send(401);
    }
},

ensureAdmin: function(req, res, next) {
  // ensure authenticated user exists with admin role, 
  // otherwise send 401 response status
  if (req.user && req.user.role == 'ADMIN') {
      return next();
  } else {
      return res.send(401);
  }
},

Outras dicas

Ainda não uso opassportjs, mas acabei de fazer a mesma coisa que você está procurando.Aqui está meu exemplo de configuração:

// Example configuration
var express = require('express');
var routes = require('./routes');
var app = express();

app.configure(function(){
    app.use(express.bodyParser());
    app.use(express.cookieParser('shhhh, very secret'));
    app.use(express.session());
    app.use(express.favicon());
    app.use(express.logger('dev'));
    app.use(express.compress());
    app.use('/', express.static(expressAppdir)); // look for overrides on express server 1st
    app.use('/', express.static(appDir));
   // app.use(express.methodOverride()); 
    app.use(app.router);

    app.use(function(req, res, next){
      var err = req.session.error
        , msg = req.session.success;
      delete req.session.error;
      delete req.session.success;
      res.locals.message = '';
      if (err) res.locals.message = '<p class="msg error">' + err + '</p>';
      if (msg) res.locals.message = '<p class="msg success">' + msg + '</p>';
      next();
    });

});

app.configure(function() {
    // gets
    app.get('/', routes.root);
    app.get('/login', routes.login);
    app.get('/logout', routes.logout);    

    app.get('/restricted/test/:slug', restrict, routes.restrictedGet); // must be last API route, slug is any request on the end of the routes that is requested.

    app.post('/login', routes.loginPost);
});

function restrict(req, res, next) {
  console.dir('restrict called');
  if (req.session.user) {
    next();
  } else {
    req.session.error = 'Access denied!';
    res.redirect('/login');
  }
}

//Routes.js file

// my dummy login (in a separate file)

var passport = require('passport')
  , LocalStrategy = require('passport-local').Strategy;

  passport.use(new LocalStrategy(
  function(username, password, done) {
    User.findOne({ username: username }, function (err, user) {
      if (err) { return done(err); }
      if (!user) {
        return done(null, false, { message: 'Incorrect username.' });
      }
      if (!user.validPassword(password)) {
        return done(null, false, { message: 'Incorrect password.' });
      }
      return done(null, user);
    });
  }
));

exports.restrictedGet = function (req, res, next) {
  console.dir('reached restricted get');

  var slug = req.params.slug;
  console.dir(req.route);

  if(req.route.path.indexOf('test')!=-1)
  {
    namedQuery['testFunction'](req,res,next);
  }
  else
  {
    res.status(404).send('no route found. Route requested: ' + req.route.path);
  }

  // do something with your route here, check what's being appended to the slug and fire off the appropriate function.
};

exports.login = function(req, res, next) {
  res.sendfile(serverBase + "/static/public/login.html");
};

exports.logout = function(req, res, next) {
     req.session.destroy(function(){
      res.redirect('/');
    });
};

// this is where you would hook in your passportjs stuff to do hashing of inputted text and compare it to the hash stored in your db etc.
// I use my own simple authentication funciton right now as i'm just testing.

exports.loginPost = function(req, res, next) {
  authenticate(req.body.username, req.body.password, function(err, user){
    console.log('Reached login user: ', user);
    if (user) {
          // Regenerate session when signing in
          // to prevent fixation 
          req.session.regenerate(function(){

            req.session.user = user;
            req.session.success = 'Authenticated as ' + user.name
            + ' click to <a href="/logout">logout</a>. '
            + ' You may now access <a href="/restricted">/restricted</a>.';
              res.redirect('/');
            });
        } else {
          req.session.error = 'Authentication failed, please check your '
          + ' username and password.'
          + ' (use "tj" and "foobar")';
          res.json({success: false});
          res.redirect('/login');
        }
      });
};

// You could now do this with passport instead:
exports.loginPost = function(req, res, next) {
  passport.authenticate('local'), function(err, user){
    console.log('Reached login user: ', user);
    if (user) {
          // Regenerate session when signing in
          // to prevent fixation 
          req.session.regenerate(function(){

            req.session.user = user;
            req.session.success = 'Authenticated as ' + user.name
            + ' click to <a href="/logout">logout</a>. '
            + ' You may now access <a href="/restricted">/restricted</a>.';
              res.redirect('/');
            });
        } else {
          req.session.error = 'Authentication failed, please check your '
          + ' username and password.'
          + ' (use "tj" and "foobar")';
          res.json({success: false});
          res.redirect('/login');
        }
      };
};

function authenticate(name, pass, fn) {

  var user = { name:name, password: pass }
  return fn(null,user);

};

Foi daqui que tirei grande parte do meu código: http://www.breezejs.com/samples/zza, http://passportjs.org/guide/authenticate/

Espero que isto ajude!

#

EDITAR

#

Esqueci de mencionar, para o lado angular eu só tenho um formulário simples postando de volta os valores de usuário e senha para o endpoint do post de login, já que o getEndpoint é restrito, o aplicativo expresso cuidará do resto do lado de autenticação e restrição das coisas para você.Se eu puder ajudar em mais alguma coisa, não hesite em perguntar.

Eu conheci duas soluções

Angular-Cliente-Side-Auth e angular-http-auth

Você pode encontrá-lo no GitHub

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top