Skip to content

Commit

Permalink
feat(jwt): adding initial support for jwt authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
lirantal committed Sep 12, 2017
1 parent 0689d0c commit 7b63c78
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 3 deletions.
3 changes: 3 additions & 0 deletions server/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ module.exports = {
minOptionalTestsToPass: 4
}
},
jwt: {
secret: process.env.FACEBOOK_ID || 'test'
},
facebook: {
clientID: process.env.FACEBOOK_ID || 'APP_ID',
clientSecret: process.env.FACEBOOK_SECRET || 'APP_SECRET',
Expand Down
28 changes: 28 additions & 0 deletions server/modules/users/server/config/strategies/jwt.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use strict'

const passport = require('passport')
const passportJwt = require('passport-jwt')
const UserService = require('../../services/user.service')

const JwtStrategy = passportJwt.Strategy
const ExtractJwt = passportJwt.ExtractJwt

module.exports = function (config) {
passport.use(new JwtStrategy({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: config.jwt.secret
}, async (jwtPayload, done) => {
try {
const user = await UserService.getUserDeserializedById(jwtPayload.id)
if (user) {
return done(null, user)
} else {
return done(null, false, {
message: 'Incorrect token'
})
}
} catch (err) {
return done(err)
}
}))
}
4 changes: 2 additions & 2 deletions server/modules/users/server/config/strategies/local.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
'use strict';
'use strict'

/**
* Module dependencies
Expand All @@ -8,7 +8,7 @@ const LocalStrategy = require('passport-local').Strategy
// const User = require('mongoose').model('User')
const UserService = require('../../services/user.service')

module.exports = function () {
module.exports = function (config) {
passport.use(new LocalStrategy({
usernameField: 'usernameOrEmail',
passwordField: 'password'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
* Module dependencies
*/
const path = require('path')
const config = require(path.resolve('./lib/config'))
const errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller'))
const mongoose = require('mongoose')
const passport = require('passport')
const jwt = require('jsonwebtoken')
const User = mongoose.model('User')

const UserService = require('../../services/user.service')
Expand Down Expand Up @@ -44,6 +46,33 @@ exports.signout = function (req, res) {
return res.status(200).send()
}

/**
* Jwt Token Auth
*/
exports.token = async function (req, res) {
try {
// Authenticate the user based on credentials
// @TODO be consistent with whether the login field for user identification
// is a username or an email
const username = req.body.email
const password = req.body.password
const user = await UserService.authenticate(username, password)

// Create the token and send
// @TODO properly create the token with all of its metadata
const payload = {
id: user.id
}
// @TODO properly sign the token, not with a shared secret (use pubkey instead),
// and specify proper expiration, issuer, algorithm, etc.
const token = jwt.sign(payload, config.jwt.secret)

res.status(200).json({token: token})
} catch (err) {
return res.status(500).send(err.message)
}
}

/**
* OAuth provider call
*/
Expand Down
10 changes: 10 additions & 0 deletions server/modules/users/server/routes/auth.server.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ module.exports = function (app) {
app.route('/api/auth/signin').post(passport.authenticate('local'), users.signin)
app.route('/api/auth/signout').post(users.signout)

// Jwt token
app.route('/api/auth/token').post(users.token)
// Jwt protected route example:
// app.route('/api/auth/secretPlace').get(passport.authenticate('jwt'), (req, res) => {
// console.log(req.user)
// console.log(req.session)
// console.log(req.isAuthenticated())
// res.status(200).send()
// })

// Setting the facebook oauth routes
app.route('/api/auth/facebook').get(users.oauthCall('facebook', {
scope: ['email']
Expand Down
4 changes: 4 additions & 0 deletions server/modules/users/server/services/user.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ const SALT_ROUNDS = 10

class UserService {
static deserialize (user) {
if (!user || typeof user !== 'object') {
return null
}

return {
id: user.id,
displayName: user.displayName,
Expand Down
4 changes: 3 additions & 1 deletion server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"gulp-ava": "^0.15.0",
"helmet": "~2.3.0",
"jasmine-core": "~2.5.0",
"jsonwebtoken": "^8.0.0",
"lodash": "~4.16.2",
"lusca": "~1.4.1",
"method-override": "~2.3.5",
Expand All @@ -59,10 +60,11 @@
"nodemailer": "~2.6.4",
"nodemon": "^1.11.0",
"owasp-password-strength-test": "~1.3.0",
"passport": "~0.3.2",
"passport": "^0.3.2",
"passport-facebook": "~2.1.0",
"passport-github": "~1.1.0",
"passport-google-oauth": "~1.0.0",
"passport-jwt": "^3.0.0",
"passport-linkedin": "~1.0.0",
"passport-local": "~1.0.0",
"passport-paypal-openidconnect": "~0.1.1",
Expand Down

0 comments on commit 7b63c78

Please sign in to comment.