2013-08-15 30 views
11

Sono nuovo in PassportJS e AngularJS e ho un dubbio su come procedere con questa autorizzazione.Angular JS + Node JS + Passport + Spring OAuth2 Autenticazione/Autorizzazione

devo Primavera REST API Secured by OAuth2, ma devo inviare insieme credenziali utente in questo modo:

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

In cliente mia domanda io uso del passaporto e voglio autorizzazione/autenticazione miei utenti, come si può Creo una Stratagy per questo?

Invierò qui il mio server di configurazione e la mia sicurezza 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; 

non so se devo usare il passaporto Portatore oppure no e come usarlo.

Grazie in anticipo per qualsiasi aiuto.

Saluti,

Eduardo.

+0

Per la parte OAuth2, suppongo che voi avete visto: https://github.com/jaredhanson/oauth2orize/tree/master/examples/express2 –

+1

Spiacente, ignorare il mio commento, mi manca leggere, il mio link è per il server OAuth2 che hai già e vuoi collegarti. Non sono ancora al cliente. –

+0

Ecco un'app di esempio che utilizza everyauth: https://github.com/ganarajpr/express-angular –

risposta

7

Non so se devo utilizzare il passport-Bearer o meno e come usarlo.

No. Ci sono altre opzioni, come ad esempio:

Ecco un esempio di come utilizzare il passaporto:

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

Riferimenti