Last active
April 6, 2017 11:52
-
-
Save ydomenjoud/c0f4fdc3a1ee0adb885f298b4102365e to your computer and use it in GitHub Desktop.
install sails and configure for jwt auth
This file contains 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
#!/bin/sh | |
######################### | |
# secure sails api by jwt | |
######################### | |
project_name='project' | |
# install sails | |
sudo npm -g install sails | |
sails new $project_name --no-frontend | |
cd $project_name | |
npm i --save jsonwebtoken passport passport-jwt passport-local bcrypt-nodejs | |
sails generate controller user | |
# create files | |
cat > api/services/AuthService.js <<EOF | |
let bcrypt = require('bcrypt-nodejs'); | |
let jwt = require('jsonwebtoken'); | |
module.exports = { | |
hashPassword: function(user) { | |
if (user.password) { | |
user.password = bcrypt.hashSync(user.password); | |
} | |
}, | |
comparePassword: function(password, user) { | |
return bcrypt.compareSync(password, user.password); | |
}, | |
createToken: function(user) { | |
return jwt.sign({ | |
user: user.toJSON(), | |
}, | |
sails.config.jwt.secretOrKey, | |
{ | |
algorithm: sails.config.jwt.algorithm, | |
expiresIn: sails.config.jwt.expiresInMinutes, | |
issuer: sails.config.jwt.issuer, | |
audience: sails.config.jwt.audience, | |
} | |
); | |
}, | |
localStrategy(email, password, next) { | |
User.findOne({email: email}) | |
.exec(function(error, user) { | |
if (error) return next(error, false, {}); | |
if (!user) return next(null, false, { | |
code: 'E_USER_NOT_FOUND', | |
message: email + ' is not found' | |
}); | |
if (!AuthService.comparePassword(password, user)) { | |
return next(null, false, { | |
code: 'E_WRONG_PASSWORD', | |
message: 'Password is wrong' | |
}); | |
} | |
return next(null, user, {}); | |
}); | |
}, | |
jwtStrategy(req, payload, next) { | |
let user = payload.user; | |
// do your things with user like recording usage of api | |
return next(null, user, {}); | |
}, | |
passportAuth(req, res, error, user, info) { | |
if (error) return res.serverError(error); | |
if (!user) { | |
return res.forbidden({code: info.code, message: info.message}); | |
} | |
return res.ok({ | |
token: AuthService.createToken(user), | |
user: user, | |
}); | |
} | |
}; | |
EOF | |
cat > api/controllers/AuthController.js <<EOF | |
/** | |
* AuthController | |
* | |
* @description :: Server-side logic for managing Auths | |
* @help :: See http://sailsjs.org/#!/documentation/concepts/Controllers | |
*/ | |
let passport = require('passport'); | |
module.exports = { | |
register: function(req, res) { | |
User | |
.create(_.omit(req.allParams(), 'id')) | |
.then(function(user) { | |
return user; | |
}) | |
.then(res.created) | |
.catch(res.serverError); | |
}, | |
login: function(req, res) { | |
passport.authenticate('local', | |
AuthService.passportAuth.bind(this, req, res))(req, res); | |
}, | |
}; | |
EOF | |
cat > api/models/User.js <<EOF | |
/** | |
* User.js | |
* | |
* @description :: TODO: You might write a short summary of how this model works and what it represents here. | |
* @docs :: http://sailsjs.org/documentation/concepts/models-and-orm/models | |
*/ | |
let hash = function(values, next) { | |
AuthService.hashPassword(values); | |
next(); | |
}; | |
module.exports = { | |
attributes: { | |
password: { | |
type: 'string', | |
}, | |
email: { | |
type: 'string', | |
email: true, | |
required: true, | |
unique: true, | |
}, | |
}, | |
beforeUpdate: hash, | |
beforeCreate: hash, | |
} | |
EOF | |
cat > api/policies/isAuthenticated.js <<EOF | |
/** | |
* isAuthenticated | |
* @description :: Policy to inject user in req via JSON Web Token | |
*/ | |
const passport = require('passport'); | |
module.exports = function(req, res, next) { | |
passport.authenticate('jwt', function(error, user, info) { | |
if (error) return res.serverError(error); | |
if (!user) | |
return res.forbidden({code: info.code, message: info.message}); | |
req.user = user; | |
next(); | |
})(req, res); | |
}; | |
EOF | |
cat > config/passport.js <<EOF | |
const passport = require('passport'); | |
const LocalStrategy = require('passport-local').Strategy; | |
const JwtStrategy = require('passport-jwt').Strategy; | |
const ExtractJwt = require('passport-jwt').ExtractJwt; | |
const AuthService = require('../api/services/AuthService'); | |
let EXPIRES_IN = process.env.JWT_EXPIRE_IN || '1d'; | |
let SECRET = process.env.JWT_SECRET || 'mysecret'; | |
let ALGORITHM = process.env.JWT_ALGORITHM || 'HS256'; | |
let ISSUER = process.env.JWT_ISSUER || 'mysite.com'; | |
let AUDIENCE = process.env.JWT_AUDIENCE || 'mysite.com'; | |
const LOCAL_STRATEGY_CONFIG = { | |
usernameField: 'email', | |
passwordField: 'password', | |
passReqToCallback: false | |
}; | |
const JWT_STRATEGY_CONFIG = { | |
expiresIn: EXPIRES_IN, | |
secretOrKey: SECRET, | |
issuer: ISSUER, | |
algorithm: ALGORITHM, | |
audience: AUDIENCE, | |
jwtFromRequest: ExtractJwt.fromAuthHeader(), | |
passReqToCallback: true | |
}; | |
passport.use( new LocalStrategy(LOCAL_STRATEGY_CONFIG, AuthService.localStrategy)); | |
passport.use( new JwtStrategy(JWT_STRATEGY_CONFIG, AuthService.jwtStrategy)); | |
module.exports.jwt = JWT_STRATEGY_CONFIG; | |
EOF | |
cat > config/policies.js <<EOF | |
module.exports.policies = { | |
'*': ['isAuthenticated'], | |
'AuthController': { | |
'*': true, | |
}, | |
} | |
EOF | |
# edit config files | |
sed -i '/allRoutes/ s,^.*//,,g' config/cors.js | |
sed -i '/migrate/ s,^.*//,,g' config/models.js | |
echo "everything is installed" | |
# lift sails | |
sails lift |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment