2013-08-15 32 views
11

Tôi mới tham gia PassportJS và AngularJS và tôi có nghi ngờ về cách tiến hành ủy quyền này.Angular JS + Node JS + Hộ chiếu + Xác thực/Cấp phép Spring OAuth2

Tôi có mùa xuân REST API bảo đảm bởi OAuth2, nhưng tôi phải gửi kèm thông tin người dùng như thế này:

[http://localhost:8080/myapp/oauth/token] 
grant_type=password&username=email&password=password&client_id=09e749d8309f4044&client_secret=189309492722aa5a&scope=read 

Trong client ứng dụng của tôi, tôi sử dụng hộ chiếu và tôi muốn ủy quyền/xác thực người dùng của tôi, làm thế nào có thể Tôi tạo ra một Stratagy cho điều này?

Tôi sẽ gửi ở đây cấu hình máy chủ và bảo mật của tôi Lib.

Server.js



    var fs = require('fs'); 
    var http = require('http'); 
    var https = require('https'); 
    var privateKey = fs.readFileSync(__dirname + '/cert/privatekey.pem').toString(); 
    var certificate = fs.readFileSync(__dirname + '/cert/certificate.pem').toString(); 
    var credentials = {key: privateKey, cert: certificate}; 

    var express = require('express'); 
    var config = require('./config.js'); 
    var passport = require('passport'); 
    var security = require('./lib/security'); 
    var xsrf = require('./lib/xsrf'); 
    var protectJSON = require('./lib/protectJSON'); 
    require('express-namespace'); 

    var app = express(); 
    var secureServer = https.createServer(credentials, app); 
    var server = http.createServer(app); 

    // Serve up the favicon 
    app.use(express.favicon(config.server.distFolder + '/favicon.ico')); 

    // First looks for a static file: index.html, css, images, etc. 
    app.use(config.server.staticUrl, express.compress()); 
    app.use(config.server.staticUrl, express['static'](config.server.distFolder)); 
    app.use(config.server.staticUrl, function(req, res, next) { 
     res.send(404); // If we get here then the request for a static file is invalid 
    }); 

    app.use(protectJSON); 

    app.use(express.logger());         // Log requests to the console 
    app.use(express.bodyParser());        // Extract the data from the body of the request - this is needed by the LocalStrategy authenticate method 
    app.use(express.cookieParser(config.server.cookieSecret)); // Hash cookies with this secret 
    app.use(express.cookieSession());       // Store the session in the (secret) cookie 
    app.use(passport.initialize());        // Initialize PassportJS 
    app.use(passport.session());        // Use Passport's session authentication strategy - this stores the logged in user in the session and will now run on any request 
    app.use(xsrf);            // Add XSRF checks to the request 
    security.initialize(config.oauth.authorize_url, config.oauth.access_token, config.oauth.apiKey, config.oauth.secretKey, config.oauth.scopereq);   // Add a Oauth strategy for handling the authentication 

    app.use(function(req, res, next) { 
     if (req.user) { 
     console.log('Current User:', req.user.firstName, req.user.lastName); 
     } else { 
     console.log('Unauthenticated'); 
     } 
     next(); 
    }); 

    app.post('/login', security.login); 
    app.post('/logout', security.logout); 

    // Retrieve the current user 
    app.get('/current-user', security.sendCurrentUser); 

    // Retrieve the current user only if they are authenticated 
    app.get('/authenticated-user', function(req, res) { 
     security.authenticationRequired(req, res, function() { security.sendCurrentUser(req, res); }); 
    }); 

    // Retrieve the current user only if they are admin 
    app.get('/admin-user', function(req, res) { 
     security.adminRequired(req, res, function() { security.sendCurrentUser(req, res); }); 
    }); 

    // This route deals enables HTML5Mode by forwarding missing files to the index.html 
    app.all('/*', function(req, res) { 
     // Just send the index.html for other files to support HTML5Mode 
     res.sendfile('index.html', { root: config.server.distFolder }); 
    }); 

    // A standard error handler - it picks up any left over errors and returns a nicely formatted server 500 error 
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 

    // Start up the server on the port specified in the config 
    server.listen(config.server.listenPort, 'localhost', 511, function() { 
     // // Once the server is listening we automatically open up a browser 
     var open = require('open'); 
     open('http://localhost:' + config.server.listenPort + '/'); 
    }); 
    console.log('Deengo Business App Server - listening on port: ' + config.server.listenPort); 
    secureServer.listen(config.server.securePort); 
    console.log('Deengo Business App Server - listening on secure port: ' + config.server.securePort); 

lib/security.js



    var express = require('express'); 
    var passport = require('passport'); 
    var app = express(); 
    var BearerStrategy = require('passport-http-bearer').Strategy 

    var filterUser = function(user) { 
     if (user) { 
     return { 
      user : { 
      id: user._id.$oid, 
      email: user.email, 
      firstName: user.firstName, 
      lastName: user.lastName, 
      admin: user.admin 
      } 
     }; 
     } else { 
     return { user: null }; 
     } 
    }; 

    var security = { 
     initialize: function(_authorize_url, _access_token, _apiKey, _secretKey, _scopereq) { 
     passport.use('deengo-auth', new OAuth2Strategy({ 
      authorizationURL: _authorize_url, 
      tokenURL: _access_token, 
      clientID: _apiKey, 
      clientSecret: _secretKey, 
      callbackURL: 'http://localhost:3000/oauth/autorize/callback', 
      scope: _scopereq, 
      passReqToCallback: true, 
      skipUserProfile: true   
      }, 
      function(req, accessToken, refreshToken, profile, done) { 
      client['headers']['authorization'] = 'bearer ' + req.session.passport.accessToken;   
      User.findOrCreate({ clientId: clientId }, function(err, user) { 
       done(err, user); 
      }); 
      } 
     )); 

     }, 
     authenticationRequired: function(req, res, next) { 
     console.log('authRequired'); 
     if (req.isAuthenticated()) { 
      next(); 
     } else { 
      res.json(401, filterUser(req.user)); 
     } 
     }, 
     adminRequired: function(req, res, next) { 
     console.log('adminRequired'); 
     if (req.user && req.user.admin) { 
      next(); 
     } else { 
      res.json(401, filterUser(req.user)); 
     } 
     }, 
     sendCurrentUser: function(req, res, next) { 
     res.json(200, filterUser(req.user)); 
     res.end(); 
     }, 
     login: function(req, res, next) { 

     console.log(req.body.email); 
     console.log(req.body.password); 

     function authenticationFailed(err, user, info){ 

      //if (err) { return next(err); } 
      /*if (!user) { return res.json(filterUser(user)); } 
      req.logIn(user, function(err) { 
      if (err) { return next(err); } 
      return res.json(filterUser(user)); 
      });*/ 
     } 
     //passport.authenticate("deengo-auth", authenticationFailed)(req, res, next); 
     return null; 
     }, 
     logout: function(req, res, next) { 
     req.logout(); 
     res.send(204); 
     } 
    }; 

    module.exports = security; 

lib/DeengoStrategy.js



    var util = require('util'); 
    var passport = require('passport'); 
    var LocalStrategy = require('passport-local').Strategy; 
    var BearerStrategy = require('passport-http-bearer').Strategy; 
    var rest = require('request'); 

    function DeengoRestStrategy(authorize_url, access_token, apiKey, secretKey, scopereq) { 
     this.authorize_url = authorize_url; 
     this.access_token = access_token; 
     this.apiKey = apiKey; 
     this.secretKey = secretKey; 
     this.scopereq = secretKey; 
     this.baseUrl = 'http://localhost:8080/deengo/api/'; 

     // Call the super constructor - passing in our user verification function 
     // We use the email field for the username 
     LocalStrategy.call(this, { usernameField: 'email' }, this.verifyUser.bind(this)); 

     // Serialize the user into a string (id) for storing in the session 
     passport.serializeUser(function(user, done) { 
     done(null, user.id); 
     }); 

     // Deserialize the user from a string (id) into a user (via a cll to REST) 
     passport.deserializeUser(this.get.bind(this)); 

     // We want this strategy to have a nice name for use by passport, e.g. app.post('/login', passport.authenticate('deengo')); 
     this.name = DeengoRestStrategy.name; 
    } 

    // DeengoRestStrategy inherits from LocalStrategy 
    util.inherits(DeengoRestStrategy, LocalStrategy); 

    DeengoRestStrategy.name = "deengo"; 

    // Query the users collection 
    DeengoRestStrategy.prototype.query = function(query, done) { 
     query.accessToken = this.accessToken;  // Add the apiKey to the passed in query 
     var request = rest.get(this.baseUrl, { qs: query, json: {} }, function(err, response, body) { 
     done(err, body); 
     }); 
    }; 

    // Get a user by id 
    DeengoRestStrategy.prototype.get = function(id, done) { 
     var query = { apiKey: this.apiKey }; 
     var request = rest.get(this.baseUrl + id, { qs: query, json: {} }, function(err, response, body) { 
     done(err, body); 
     }); 
    }; 

    // Find a user by their email 
    DeengoRestStrategy.prototype.findByEmail = function(email, done) { 
     this.query({ q: JSON.stringify({email: email}) }, function(err, result) { 
     if (result && result.length === 1) { 
      return done(err, result[0]); 
     } 
     done(err, null); 
     }); 
    }; 

    // Check whether the user passed in is a valid one 
    DeengoRestStrategy.prototype.verifyUser = function(email, password, done) { 
     this.findByEmail(email, function(err, user) { 
     if (!err && user) { 
      if (user.password !== password) { 
      user = null; 
      } 
     } 
     done(err, user); 
     }); 
    }; 

    module.exports = DeengoRestStrategy; 

Tôi không biết nếu tôi phải sử dụng hộ chiếu-Bearer hay không và cách sử dụng nó.

Cảm ơn trước vì đã được trợ giúp.

Trân trọng,

Eduardo.

+0

Đối với phần OAuth2, tôi giả sử bạn đã thấy: https://github.com/jaredhanson/oauth2orize/tree/master/examples/express2 –

+1

Xin lỗi, bỏ qua nhận xét của tôi, tôi nhớ đã đọc, liên kết của tôi là dành cho máy chủ OAuth2 mà bạn đã có và muốn kết nối. Tôi chưa ở khách hàng. –

+0

Đây là một ứng dụng ví dụ sử dụng everyauth: https://github.com/ganarajpr/express-angular –

Trả lời

7

Tôi không biết mình có phải sử dụng hộ chiếu-Bearer hay không và cách sử dụng nó.

số có các tùy chọn khác, chẳng hạn như:

Dưới đây là một ví dụ về cách sử dụng hộ chiếu:

// Express using passport-local 
// This code is adaptation of examples/express3 from https://github.com/jaredhanson/passport-local 


// configure Express 
app.configure(function() { 
// ... 
app.use(express.session({ 
// The domain should start with a dot, as this allows the subdomain. 
domain: '.app.local', 
secret: 'keyboard cat' 
})); 

// Enable cors. 
app.use(function(req, res, next) { 
res.header('Access-Control-Allow-Credentials', true); 
res.header('Access-Control-Allow-Origin', req.headers.origin); 
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE'); 
res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept'); 
next(); 
}); 

// ... 
}); 

app.get('/account', ensureAuthenticated, function(req, res){ 
// Return the current user's info 
res.json(req.user); 
}); 

Tài liệu tham khảo

Các vấn đề liên quan