Skip to content
Snippets Groups Projects
Commit e3b7fbf6 authored by Vytor Calixto's avatar Vytor Calixto :space_invader:
Browse files

[ci skip]Change passport auth to use oauth2

parent be7f2982
No related branches found
No related tags found
2 merge requests!116Release v1.0.0,!73Workerpool feature
Pipeline #
......@@ -16,8 +16,7 @@
"url": "http://simcaqdb3.c3sl.ufpr.br:3000"
},
"mongodb" : {
"uri": "mongodb://localhost/dev_users",
"secret": "SimCAQC3SL"
"uri": "mongodb://localhost/dev_users"
},
"monq": {
"uri": "mongodb://localhost/dev_monq"
......@@ -33,6 +32,9 @@
"secure": false,
"ignoreTLS": true,
"from": "\"Laboratório de Dados Educacionais\" <lde@c3sl.ufpr.br>"
},
"security": {
"tokenLife": 3600
}
},
"test":
......@@ -69,6 +71,9 @@
"secure": false,
"ignoreTLS": true,
"from": "\"Laboratório de Dados Educacionais\" <lde@c3sl.ufpr.br>"
},
"security": {
"tokenLife": 3600
}
},
"production":
......@@ -105,6 +110,9 @@
"secure": false,
"ignoreTLS": true,
"from": "\"Laboratório de Dados Educacionais\" <lde@c3sl.ufpr.br>"
},
"security": {
"tokenLife": 3600
}
}
}
const oauth2orize = require('oauth2orize');
const passport = require('passport');
const crypto = require('crypto');
const libs = `${process.cwd()}/libs`;
const config = require(`${libs}/config`);
const log = require(`${libs}/log`)(module);
const db = require(`${libs}/db/mongoose`);
const User = require(`${libs}/models/user`);
const AccessToken = require(`${libs}/model/accessToken`);
const RefreshToken = require(`${libs}/model/refreshToken`);
// create OAuth 2.0 server
let aserver = oauth2orize.createServer()
// Generic error handler
let errFn = (cb, err) => {
if (err) {
return cb(err)
}
}
// Destroys any old tokens and generates a new access and refresh token
let generateTokens = (data, done) => {
// curries in `done` callback so we don't need to pass it
let errorHandler = errFn.bind(undefined, done);
let refreshToken;
let refreshTokenValue/
let token;
let tokenValue;
RefreshToken.remove(data, errorHandler);
AccessToken.remove(data, errorHandler);
tokenValue = crypto.randomBytes(32).toString('hex');
refreshTokenValue = crypto.randomBytes(32).toString('hex');
data.token = tokenValue;
token = new AccessToken(data);
data.token = refreshTokenValue;
refreshToken = new RefreshToken(data);
refreshToken.save(errorHandler);
token.save((err) => {
if (err) {
log.error(err);
return done(err);
}
done(null, tokenValue, refreshTokenValue, {
'expires_in': config.get('security:tokenLife')
});
})
};
// Exchange username & password for access token.
aserver.exchange(oauth2orize.exchange.password((client, email, password, scope, done) => {
User.findOne({ email }, (err, user) => {
if (err) {
return done(err);
}
if (!user || !user.checkPassword(password)) {
return done(null, false);
}
var model = {
userId: user._id,
clientId: client._id
};
generateTokens(model, done);
})
}));
// Exchange refreshToken for access token.
aserver.exchange(oauth2orize.exchange.refreshToken((client, refreshToken, scope, done) =>{
RefreshToken.findOne({ token: refreshToken, clientId: client._id }, (err, token) => {
if (err) {
return done(err);
}
if (!token) {
return done(null, false);
}
User.findById(token.userId, (err, user) => {
if (err) {
log.error(err);
return done(err);
}
if (!user) {
return done(null, false);
}
var model = {
userId: user._id,
clientId: client._id
};
generateTokens(model, done);
})
})
}))
// token endpoint
//
// `token` middleware handles client requests to exchange authorization grants
// for access tokens. Based on the grant type being exchanged, the above
// exchange middleware will be invoked to handle the request. Clients must
// authenticate when making requests to this endpoint.
exports.token = [
passport.authenticate(['oauth2-client-password'], { session: false }),
aserver.token(),
aserver.errorHandler()
];
const JwtStrategy = require('passport-jwt').Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;
const passport = require('passport');
const ClientPasswordStrategy = require('passport-oauth2-client-password');
const BearerStrategy = require('passport-http-bearer').Strategy;
const libs = `${process.cwd()}/libs`;
const config = require(`${libs}/config`);
const User = require(`${libs}/models/user`)
module.exports = function(passport){
var opts = {};
opts.jwtFromRequest = ExtractJwt.fromAuthHeader();
opts.secretOrKey = config.get('mongodb:secret');
passport.use(new JwtStrategy(opts, function(jwt_payload, done){
User.find({email: jwt_payload.email}, function(err, user){
const User = require(`${libs}/models/user`);
const Client = require(`${libs}/models/client`);
const AccessToken = require(`${libs}/models/accessToken`);
const RefreshToken = require(`${libs}/models/refreshToken`);
const email = require(`${libs}/middlewares/email`);
passport.use(new ClientPasswordStrategy( (clientId, clientSecret, done) => {
Client.findOne({ _id: clientId }, (err, client) => {
if (err) {
return done(err);
}
if (!user) {
return done(null, false, {message: 'Unknown user'});
if (!client) {
return done(null, false);
}
return done(null, user);
});
}));
};
if (client.clientSecret !== clientSecret) {
return done(null, false);
}
/* To check if a user has access to a route, one must use passport.authenticate() specifying 'JWT' as the strategy in the route declaration, like so:
//pass passportfor configuration
require('./config/passport')(passport);
return done(null, client);
})
}
));
app.post('/route', passport.authenticate('jwt', { session: false}), function(req, res) { });
passport.use(new BearerStrategy( (accessToken, done) => {
AccessToken.findOne({ token: accessToken }, (err, token) => {
if (err) {
return done(err);
}
if (!token) {
return done(null, false);
}
if( Math.round((Date.now()-token.created)/1000) > config.get('security:tokenLife') ) {
AccessToken.remove({ token: accessToken }, (err) => {
if (err) {
return done(err);
}
});
return done(null, false, { msg: 'Token expired' });
}
the user object is then accessible via req.user
----
Usuario.findById(token.userId, function(err, usuario) {
if (err) {
return done(err);
}
Another way to check if a user is authenticated, is to check the request header for the json web token, like so:
if (!usuario) {
return done(null, false, { msg: 'Unknown user' });
}
getToken = function (headers) {
if (headers && headers.authorization) {
var parted = headers.authorization.split(' ');
if (parted.length === 2) {
return parted[1];
} else {
return null;
var info = { scope: '*' };
done(null, usuario, info);
})
})
}
} else {
return null;
}
};
var token = getToken(req.headers);
if (token) {
var decoded = jwt.decode(token, config.get(mongodb.secret));
}
*/
));
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment