Last active
July 2, 2018 02:02
-
-
Save ezy/fe883a5acdcbfdf279081dbf42ab8b88 to your computer and use it in GitHub Desktop.
JWT Passport example article
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const jwt = require('jsonwebtoken'); | |
const passport = require('passport'); | |
const config = require('../config/config'); | |
const validateEmail = require('../utils/helpers.js').validateEmail; | |
const validatePassword = require('../utils/helpers.js').validatePassword; | |
function signToken(req, res, err, user, info) { | |
if (err || !user) { | |
return res.status(400).json({ | |
message: info.message | |
}); | |
} | |
req.login(user, { session: false }, (error) => { | |
if (error) { | |
return res.send(error); | |
} | |
// generate a signed son web token with the contents of user object and return it in the response | |
const token = jwt.sign(user, config.secrets.jwt, { expiresIn: 86400 * 30 }); | |
// Use to ensure token is valid and debug non-working bearer | |
// jwt.verify(token, config.secrets.jwt, (errs, data) => { | |
// console.log(errs, data); | |
// }); | |
return res.json({ | |
user, | |
message: info.message, | |
token | |
}); | |
}); | |
} | |
function verifyUser(req, res /*, next*/) { | |
passport.authenticate('local-login', { session: false }, (err, user, info) => { | |
signToken(req, res, err, user, info); | |
})(req, res); | |
} | |
// Register new user | |
function registerUser(req, res) { | |
const email = req.body.email ? req.body.email.trim() : ''; | |
const password = req.body.password ? req.body.password.trim() : ''; | |
if (!email || !password) { | |
return res | |
.status(422) | |
.send({ error: 'Email, and password are required.' }); | |
} | |
const emailValidationError = validateEmail(email); | |
if (emailValidationError.length > 0) { | |
return res | |
.status(400) | |
.send({ error: emailValidationError }); // array of errors | |
} | |
const passwordValidationError = validatePassword(password); | |
if (passwordValidationError.length > 0) { | |
return res | |
.status(400) | |
.send({ error: passwordValidationError }); | |
} | |
passport.authenticate('local-register', { session: false }, (err, user, info) => { | |
signToken(req, res, err, user, info); | |
})(req, res); | |
} | |
module.exports = { | |
verifyUser, | |
registerUser | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const config = require('../config/config'); | |
const passport = require('passport'); | |
const LocalStrategy = require('passport-local').Strategy; | |
const User = require('../../models').User; | |
const passportJWT = require('passport-jwt'); | |
const JWTStrategy = passportJWT.Strategy; | |
const ExtractJWT = passportJWT.ExtractJwt; | |
const bcrypt = require('bcrypt'); | |
passport.use('local-login', new LocalStrategy({ | |
usernameField: 'email', | |
passwordField: 'password' | |
}, | |
(email, password, cb) => { | |
// Sequelize will find the user with raw data returned | |
User.findOne({where: {email},raw: true}) | |
.then((user) => { | |
if (!user) { | |
return cb(null, false, { | |
message: 'Incorrect email or password.' | |
}); | |
} | |
// Don't forget bcrypt as passwords are encrypted | |
if (!bcrypt.compareSync(password, user.password)) { | |
return cb(null, false, { | |
message: 'Incorrect email or password.' | |
}); | |
} | |
return cb(null, user, { | |
message: 'Logged in successfully' | |
}); | |
}) | |
.catch((err) => cb(err)); | |
} | |
)); | |
passport.use('local-register', new LocalStrategy({ | |
usernameField: 'email', | |
passwordField: 'password' | |
}, (email, password, cb) => { | |
// Sequelize will find the user with raw data returned | |
User.findOne({where: {email},raw: true}) | |
.then((user) => { | |
if (user) { | |
return cb(null, false, { | |
message: 'The email is already registered.' | |
}); | |
} | |
const salt = bcrypt.genSaltSync(10); | |
const hash = bcrypt.hashSync(password, salt); | |
const userObj = { | |
email, | |
password: hash | |
}; | |
User.create(userObj) | |
.then((newUser) => { | |
const dataObj = newUser.get({plain:true}); | |
return cb(null, dataObj, { | |
message: 'User created successfully.' | |
}); | |
}) | |
.catch((err) => { | |
return cb(err); | |
}); | |
}) | |
.catch((err) => cb(err)); | |
})); | |
passport.use(new JWTStrategy({ | |
jwtFromRequest: ExtractJWT.fromAuthHeaderWithScheme('Bearer'), | |
secretOrKey: config.secrets.jwt | |
}, | |
(jwtPayload, cb) => { | |
// Use the JWT token to find the user in the db if required | |
User.findOne({where: {email: jwtPayload.email},raw: true}) | |
.then((user) => { | |
return cb(null, user); | |
}) | |
.catch((err) => { | |
return cb(err); | |
}); | |
} | |
)); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const router = require('express').Router(); | |
const controller = require('./controller'); | |
router.route('/register') | |
.post(controller.registerUser); | |
router.route('/login') | |
.post(controller.verifyUser); | |
module.exports = router; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"dependencies": { | |
"bcrypt": "^2.0.1", | |
"body-parser": "^1.15.2", | |
"compression": "^1.6.2", | |
"cors": "^2.8.1", | |
"express": "^4.16.3", | |
"helmet": "^3.1.0", | |
"jsonwebtoken": "^8.3.0", | |
"passport": "^0.4.0", | |
"passport-jwt": "^4.0.0", | |
"passport-local": "^1.0.0", | |
"pg": "^7.4.3", | |
"pg-hstore": "^2.3.2", | |
"sequelize": "^4.37.8", | |
"sequelize-cli": "^4.0.0" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment