├── .env ├── .gitignore ├── package.json ├── README.md ├── utils.js └── server.js /.env: -------------------------------------------------------------------------------- 1 | JWT_SECRET=ABCDEF$123 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "first-node-app", 3 | "version": "1.0.0", 4 | "description": "Test project", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "nodemon server.js", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "Clue Mediator", 11 | "license": "ISC", 12 | "dependencies": { 13 | "body-parser": "^1.19.0", 14 | "cors": "^2.8.5", 15 | "dotenv": "^8.2.0", 16 | "express": "^4.17.1", 17 | "jsonwebtoken": "^8.5.1" 18 | }, 19 | "devDependencies": { 20 | "nodemon": "^2.0.0" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # auth-api-nodejs 2 | Create REST API for authentication in Node.js using JWT 3 | 4 | Please check the below link for step by step tutorial 5 | **https://www.cluemediator.com/create-rest-api-for-authentication-in-node-js-using-jwt** 6 | 7 | ## Setup 8 | Follow below steps to run project 9 | 10 | 1. Clone repository 11 | 2. Run `npm i` command to install dependencies 12 | 3. Execute `npm start` command to run the project 13 | 14 | ### Connect with us: 15 | Website: https://www.cluemediator.com 16 | Facebook: https://www.facebook.com/thecluemediator 17 | Twitter: https://twitter.com/cluemediator 18 | Telegram: https://t.me/cluemediator 19 | 20 | -------------------------------------------------------------------------------- /utils.js: -------------------------------------------------------------------------------- 1 | // generate token using secret from process.env.JWT_SECRET 2 | var jwt = require('jsonwebtoken'); 3 | 4 | // generate token and return it 5 | function generateToken(user) { 6 | //1. Don't use password and other sensitive fields 7 | //2. Use the information that are useful in other parts 8 | if (!user) return null; 9 | 10 | var u = { 11 | userId: user.userId, 12 | name: user.name, 13 | username: user.username, 14 | isAdmin: user.isAdmin 15 | }; 16 | 17 | return jwt.sign(u, process.env.JWT_SECRET, { 18 | expiresIn: 60 * 60 * 24 // expires in 24 hours 19 | }); 20 | } 21 | 22 | // return basic user details 23 | function getCleanUser(user) { 24 | if (!user) return null; 25 | 26 | return { 27 | userId: user.userId, 28 | name: user.name, 29 | username: user.username, 30 | isAdmin: user.isAdmin 31 | }; 32 | } 33 | 34 | module.exports = { 35 | generateToken, 36 | getCleanUser 37 | } 38 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config(); 2 | 3 | const express = require('express'); 4 | const cors = require('cors'); 5 | const bodyParser = require('body-parser'); 6 | const jwt = require('jsonwebtoken'); 7 | const utils = require('./utils'); 8 | 9 | const app = express(); 10 | const port = process.env.PORT || 4000; 11 | 12 | // static user details 13 | const userData = { 14 | userId: "789789", 15 | password: "123456", 16 | name: "Clue Mediator", 17 | username: "cluemediator", 18 | isAdmin: true 19 | }; 20 | 21 | // enable CORS 22 | app.use(cors()); 23 | // parse application/json 24 | app.use(bodyParser.json()); 25 | // parse application/x-www-form-urlencoded 26 | app.use(bodyParser.urlencoded({ extended: true })); 27 | 28 | 29 | //middleware that checks if JWT token exists and verifies it if it does exist. 30 | //In all future routes, this helps to know if the request is authenticated or not. 31 | app.use(function (req, res, next) { 32 | // check header or url parameters or post parameters for token 33 | var token = req.headers['authorization']; 34 | if (!token) return next(); //if no token, continue 35 | 36 | token = token.replace('Bearer ', ''); 37 | jwt.verify(token, process.env.JWT_SECRET, function (err, user) { 38 | if (err) { 39 | return res.status(401).json({ 40 | error: true, 41 | message: "Invalid user." 42 | }); 43 | } else { 44 | req.user = user; //set the user to req so other routes can use it 45 | next(); 46 | } 47 | }); 48 | }); 49 | 50 | 51 | // request handlers 52 | app.get('/', (req, res) => { 53 | if (!req.user) return res.status(401).json({ success: false, message: 'Invalid user to access it.' }); 54 | res.send('Welcome to the Node.js Tutorial! - ' + req.user.name); 55 | }); 56 | 57 | 58 | // validate the user credentials 59 | app.post('/users/signin', function (req, res) { 60 | const user = req.body.username; 61 | const pwd = req.body.password; 62 | 63 | // return 400 status if username/password is not exist 64 | if (!user || !pwd) { 65 | return res.status(400).json({ 66 | error: true, 67 | message: "Username or Password required." 68 | }); 69 | } 70 | 71 | // return 401 status if the credential is not match. 72 | if (user !== userData.username || pwd !== userData.password) { 73 | return res.status(401).json({ 74 | error: true, 75 | message: "Username or Password is Wrong." 76 | }); 77 | } 78 | 79 | // generate token 80 | const token = utils.generateToken(userData); 81 | // get basic user details 82 | const userObj = utils.getCleanUser(userData); 83 | // return the token along with user details 84 | return res.json({ user: userObj, token }); 85 | }); 86 | 87 | 88 | // verify the token and return it if it's valid 89 | app.get('/verifyToken', function (req, res) { 90 | // check header or url parameters or post parameters for token 91 | var token = req.body.token || req.query.token; 92 | if (!token) { 93 | return res.status(400).json({ 94 | error: true, 95 | message: "Token is required." 96 | }); 97 | } 98 | // check token that was passed by decoding token using secret 99 | jwt.verify(token, process.env.JWT_SECRET, function (err, user) { 100 | if (err) return res.status(401).json({ 101 | error: true, 102 | message: "Invalid token." 103 | }); 104 | 105 | // return 401 status if the userId does not match. 106 | if (user.userId !== userData.userId) { 107 | return res.status(401).json({ 108 | error: true, 109 | message: "Invalid user." 110 | }); 111 | } 112 | // get basic user details 113 | var userObj = utils.getCleanUser(userData); 114 | return res.json({ user: userObj, token }); 115 | }); 116 | }); 117 | 118 | app.listen(port, () => { 119 | console.log('Server started on: ' + port); 120 | }); 121 | --------------------------------------------------------------------------------