2013-11-15 77 views
7

我的应用使用Express和AngularJS。我使用express来通过静态方式处理角码的基本网页铺设。角码使用的服务是由Express代管的API端点。我只希望在用户通过身份验证后可以访问API端点。我怎样才能通过PassportJS来实现这一点?如何使用PassportJS保护API端点?

回答

17

我上传了一个Angular-Express project在我一直在工作的github上。

它仍在工作中。我希望它有帮助。

它使用PassportJs进行用户认证,并且是服务器端授权的基本示例。它演示了如何使API调用仅可用于已通过身份验证的用户,或者仅用于具有管理员角色的用户。这在server/routes.js实现调用中间件功能ensureAuthenticated,并在server/authentication.js

定义在routes.js在authentication.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); 
    } 
}, 
+0

项目刚刚出演。谢谢! – nkint

0

我知道两种解决方案

angular-client-side-authangular-http-auth

你可以在github上

+0

不知道我会怎样整合这些

// 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); 

ensureAdmin ... – Shamoon

2

觉得我不使用passportjs,但是我刚刚做了你正在寻找同样的事情做。这里是我的示例配置:

// 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); 

}; 

这是我得到了很多我的代码:http://www.breezejs.com/samples/zzahttp://passportjs.org/guide/authenticate/

希望这有助于!

编辑

我忘了提,针对角度身边,我只是有一个简单的形式回发的用户名和密码来登录后端点值,因为getEndpoint受到限制,快递应用程序将为您处理其他身份验证和限制事宜。如果我可以有任何进一步的帮助,请不要犹豫,问。

1

我发现了一个链接,但回到主题可能会帮助你。它不使用PassportJS(我不太熟悉它),但是您可以通过您正在使用的Express进行身份验证。

向下滚动到单路验证中的部分(本文最后一篇)。我发现这个例子非常简单,我相信你可以使用这种方法(或PassportJS)来验证你的API的路由。

链接:NODE.JS AND EXPRESS - BASIC AUTHENTICATION

如果你得到这个想通了在PassportJS,请回来后你的结果;我很想看到它。 (这也是为什么我投了你的问题)