Nodejs app with expressjs RESTAPI and JSON Web Token to check authentification sample.
Clone this repository and run:
npm install
npm start
Send a login request with curl and add two parameters:
- admin = [email protected]
- password = admin
curl -d "[email protected]&password=admin" -X POST http://localhost:8080/login
A valid token is returned:
{
"email":"[email protected]","token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjEiLCJpYXQiOjE1MjI0MjEyODAsImV4cCI6MTUyMjQyNDg4MH0.Lt4zggS4xv_nFru_Vvob_S1KGIAHth_ifxr6g4VN5R0"
}
Use that token to send next request to the API at http://localhost:8080/api/helloworld
curl -H "Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjEiLCJpYXQiOjE1MjI0MjEyODAsImV4cCI6MTUyMjQyNDg4MH0.Lt4zggS4xv_nFru_Vvob_S1KGIAHth_ifxr6g4VN5R0" -X GET "http://localhost:8080/api/helloworld"
The server check if a valid token is present in Authorization header and returns a HelloWorld:
{"message":"Helloworld"}
Try with an invalid token:
curl -H "Authorization: wrong-token" -X GET "http://localhost:8080/api/helloworld"
The server returns a token error:
{"error":"Failed to authenticate token!"}
Install the jsonwebtoken:
npm install jsonwebtoken --save
Create a middleware auth.js to check JWT. Change the secret by what do you want.
// ./routes/api/middlewares/auth.js
const jwt = require('jsonwebtoken');
const fs = require('fs');
module.exports = function (req, res, next) {
// Check if authorization header is set with a JWT valid
if (req.hasOwnProperty('headers') && req.headers.hasOwnProperty('authorization')) {
try {
// Decode JWT and keep user id (you can add more value)
req.user = jwt.verify(req.headers['authorization'], 'secret'); // secret key here
} catch (err) {
// Invalid token
return res.status(401).json({
error: 'Failed to authenticate token!'
});
}
} else {
// No token present in header
return res.status(401).json({
error: 'No token!'
});
}
next();
return;
};
Add this middleware to the /api/ route in app.js.
// ./app.js
[...]
// Add middleware. Because we defined the first parameter ( '/api' ), it will run
// only for urls that starts with '/api/*'
app.use('/api', require('./routes/api/middlewares/auth.js'));
[...]
Add a login router to generate the token.
// ./routes/login.js
const express = require('express');
const asyncHandler = require('express-async-handler');
const jwt = require('jsonwebtoken');
const fs = require('fs');
var router = express.Router();
router.route('/')
.post(asyncHandler(async (req, res, next) => {
const email = req.body.email;
const password = req.body.password;
// check login information
if (email === '[email protected]' && password === 'admin') {
// build json response with JWT valid token
let user = {
email: email,
token: jwt.sign({
id: '1',
}, 'secret', { expiresIn: 60 * 60 }) // use secret key
}
res.status(200).json(user);
}
else {
res.status(401).json({
error: 'wrong username or password!'
});
}
}))
module.exports = router;