I see that passport is discontinued
Although there is still no official communication from Jared Hanson, you can deduce that yes by the date of the last commit (May 04).
Doing it with JWT is really very simple. You only need to generate a token and a middleware that checks the token for each API request.
Benefits
- Scalability: the tokens are stored in the client but not in the backend as we would if we used sessions. In this way the application tends to make it more scalable.
- Security: when not stored in cookies we have a security bonus against CSRF attacks, and we avoid manipulating the session.
- Simplicity: when the token goes as a header in each request, we do not need to do anything other than check the integrity of the token.
Example
The first thing we must do is authenticate the user. For this we map a route in our API for it; let's say https://example.com/api/auth
.
Packages required
- express
- body-parser
- method-override
- jsonwebtoken
- bcrypt-nodejs
Authentication and token creation
import express from 'express';
import jwt from 'jsonwebtoken';
import bcrypt from 'bcrypt-nodejs';
const Router = express.Router();
Router.post('/auth', (request, response) => {
User.findOne({ name: request.body.name })
.then(user => {
if(!user) {
return response.json({
success: false,
message: 'Usuario inexistente'
});
}
if(!bcrypt.compareSync(request.body.password, user.password)) {
return response.json({
success: false,
message: 'Contraseña incorrecta'
});
}
const token = jwt.sign(user, app.get('phrase'), {
expiresInMinutes: 720 // 12 horas
});
return response.json({
success: true,
message: 'Usuario logueado',
token
});
});
});
export default Router;
Middleware
Next, we have to write the middleware to check the token on each request.
import express from 'express';
import jwt from 'jsonwebtoken';
const Router = express.Router();
Router.use((request, response, next) => {
const token = req.body.token || req.query.token || req.headers['x-access-token'];
if(token) {
jwt.verify(token, app.get('phrase'), (err, decoded) => {
if(err) {
return response.json({
success: false,
message: 'Token inválido. ¿Intentas bypassearme? >:|'
});
}
request.decoded = decoded;
next();
})
} else {
return response.json({
success: false,
message: 'No hay un token asociado a esta petición'
});
}
});
export default Router;
Finally you associate that middleware with the API url:
app.use('/api', AuthMiddleware);