diff options
author | Mateja <mail@matejamaric.com> | 2021-07-10 22:57:13 +0200 |
---|---|---|
committer | Mateja <mail@matejamaric.com> | 2021-07-10 22:57:13 +0200 |
commit | 54677c68f50b7c105a1f6cc5e9593877781fc8d6 (patch) | |
tree | 8998a76fdd76ca1170dc89cbf70423aeaf0efb0c | |
parent | fd0fafa68d638b729a506ba668165e29eea71a49 (diff) | |
download | mevn-ecommerce-54677c68f50b7c105a1f6cc5e9593877781fc8d6.tar.gz mevn-ecommerce-54677c68f50b7c105a1f6cc5e9593877781fc8d6.zip |
Implemented JWT authentication using Passport.js
-rw-r--r-- | server/config/passport.js | 29 | ||||
-rw-r--r-- | server/controllers/user.js | 47 | ||||
-rw-r--r-- | server/main.js | 4 | ||||
-rw-r--r-- | server/models/User.js | 1 | ||||
-rw-r--r-- | server/package-lock.json | 2 | ||||
-rw-r--r-- | server/package.json | 1 | ||||
-rw-r--r-- | server/routes/api.js | 5 |
7 files changed, 88 insertions, 1 deletions
diff --git a/server/config/passport.js b/server/config/passport.js new file mode 100644 index 0000000..02ad4f6 --- /dev/null +++ b/server/config/passport.js @@ -0,0 +1,29 @@ +const passport = require('passport'); +const jwtStrategy = require('passport-jwt').Strategy; +const extractJwt = require('passport-jwt').ExtractJwt; + +const {masterKey} = require("../config/env"); +const User = require('../models/User'); + +const options = { + jwtFromRequest: extractJwt.fromAuthHeaderAsBearerToken(), + secretOrKey: masterKey +}; + +const jwtStrategyCallback = (jwtPayload, done) => { + // Try to find user + User.findOne({_id: jwtPayload.sub}, (err, user) => { + // Database error + if (err) + return done(err, false); + + // No user found + if (!user) + return done(null, false); + + // Successful login + return done(null, user); + }) +}; + +passport.use(new jwtStrategy(options, jwtStrategyCallback)); diff --git a/server/controllers/user.js b/server/controllers/user.js new file mode 100644 index 0000000..e3c1078 --- /dev/null +++ b/server/controllers/user.js @@ -0,0 +1,47 @@ +const bcrypt = require('bcryptjs'); +const jwt = require('jsonwebtoken'); + +const User = require('../models/User'); +const {masterKey} = require("../config/env"); + +module.exports = { + + register(req, res) { + if (req.body.password !== req.body.confirmPassword) + res.json({status: "Passwords do not match!"}); + else { + const newUser = new User({ + firstname: req.body.firstname, + lastname: req.body.lastname, + email: req.body.email, + password: bcrypt.hashSync(req.body.password) + }); + + newUser.save() + .then(() => res.json({status: "User successfully registered!"})) + .catch(err => res.json({ + status: "Error when registering user!", + error: err + })); + } + }, + + login(req, res) { + User.findOne({email: req.body.email}, (err, user) => { + if (err) + res.json({status: "Database error.", error: err}); + + if (!bcrypt.compareSync(req.body.password, user.password)) + res.json({status: "Wrong credentials!"}); + else { + const payload = {sub: user._id}; + const token = jwt.sign(payload, masterKey, {expiresIn: "1d"}); + res.json({ + status: "Successfully logged in!", + token + }); + } + }); + } + +}; diff --git a/server/main.js b/server/main.js index 4fbb0be..bdcf9a4 100644 --- a/server/main.js +++ b/server/main.js @@ -1,6 +1,7 @@ const express = require('express'); const app = express(); const mongoose = require('mongoose'); +const passport = require('passport'); const {port, mongoUrl} = require("./config/env"); const apiRoutes = require('./routes/api'); @@ -16,6 +17,9 @@ mongoose.connection.once('open', () => console.log("Successfully connected to Mo app.use(express.json()); +require('./config/passport'); +app.use(passport.initialize()); + app.use('/api', apiRoutes); app.listen(port, () => console.log(`Server started on port ${port}.`)); diff --git a/server/models/User.js b/server/models/User.js index 401fb32..294c016 100644 --- a/server/models/User.js +++ b/server/models/User.js @@ -22,6 +22,7 @@ const UserSchema = new mongoose.Schema({ }, email: { type: String, + unique: [true, "Account with given email already exists!"], required: [true, "You need to provide an email."], maxLength: [100, "You can't have a email longer than 100 characters."], validate: { diff --git a/server/package-lock.json b/server/package-lock.json index 6b5a9bf..1864692 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -1,6 +1,6 @@ { "name": "server", - "version": "1.0.0", + "version": "0.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/server/package.json b/server/package.json index 096861b..05b399e 100644 --- a/server/package.json +++ b/server/package.json @@ -13,6 +13,7 @@ "bcryptjs": "^2.4.3", "dotenv": "^10.0.0", "express": "^4.17.1", + "jsonwebtoken": "^8.5.1", "mongoose": "^5.13.2", "passport": "^0.4.1", "passport-jwt": "^4.0.0", diff --git a/server/routes/api.js b/server/routes/api.js index 3684aa0..a0890a7 100644 --- a/server/routes/api.js +++ b/server/routes/api.js @@ -1,8 +1,13 @@ const express = require('express'); const router = express.Router(); +const passport = require('passport'); const exampleController = require('../controllers/example'); +const userController = require('../controllers/user'); router.get('/', exampleController.index); +router.get('/protected', passport.authenticate('jwt', {session: false}), exampleController.index); +router.post('/register', userController.register); +router.post('/login', userController.login); module.exports = router; |