Al crear una aplicación web, la autenticación es uno de los aspectos importantes y, por lo general, implementamos la autenticación mediante tokens JWT (puede obtener más información sobre JWT aquí ). Creamos un token de acceso y lo almacenamos en el almacenamiento local o sesión o cookie. Pero hay una forma más segura de implementar esto usando Refresh Tokens.
Refresh Tokens: Es un token único que se utiliza para obtener tokens de acceso adicionales. Esto le permite tener tokens de acceso de corta duración sin tener que recopilar credenciales cada vez que uno caduca.
Dado que los tokens de acceso no son válidos durante un período prolongado por motivos de seguridad, un token de actualización ayuda a volver a autenticar a un usuario sin credenciales de inicio de sesión. Este token de actualización nunca se expone al Javascript del lado del cliente, incluso si nuestro token de acceso se ve comprometido, caducará en muy poco tiempo. Entonces, enviaremos dos tokens en lugar de uno, un token de acceso y un token de actualización. El token de acceso contendrá toda la información del usuario y se almacenará en el tiempo de ejecución de Javascript, pero el token de actualización se almacenará de forma segura en una cookie solo de HTTP.
Persistencia de autenticación: podemos persistir fácilmente a los usuarios entre actualizaciones e inicio de sesión sin ninguna credencial. Podemos crear una nueva ruta llamada actualizar, cada vez que un token caduca o un usuario actualiza, podemos obtener un nuevo token de acceso enviando una solicitud a esta ruta
Implementación: ahora implementemos la autenticación con tokens JWT y Refresh. Comenzaremos creando una nueva aplicación Express e instalando todas las dependencias requeridas.
Paso 1: Ejecute los siguientes comandos para inicializar el proyecto y crear un archivo de índice y un archivo env. (Asegúrese de tener node y npm instalados)
npm init -y
touch index.js .env
Paso 2: Instale todas las dependencias requeridas y abra el proyecto en el editor de código.
npm install express cookie-parser dontenv jsonwebtoken
Estructura del proyecto:
Escribiremos nuestra lógica de autenticación en Index.js. Primero crearemos una aplicación rápida y luego implementaremos dos rutas de inicio de sesión y actualización . La ruta de inicio de sesión recibirá una solicitud posterior, luego verificará las credenciales si coinciden, enviará un token de actualización y un token de acceso en respuesta. La ruta de actualización también recibirá una solicitud posterior, verificará el token de actualización, si es correcto, responderá con un nuevo token de acceso; de lo contrario, arrojará un error de autorización.
Ejemplo: ahora implementaremos dos rutas de inicio de sesión y actualización. El siguiente código es para index.js:
índice.js
const dotenv = require('dotenv');
const express = require('express');
const cookieparser = require('cookie-parser');
const jwt = require('jsonwebtoken')
const bodyParser = require('body-parser');
// Configuring dotenv
dotenv.config();
const app = express();
// Setting up middlewares to parse request body and cookies
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieparser());
const userCredentials = {
username: 'admin',
password: 'admin123',
email: 'admin@gmail.com'
}
app.post('/login', (req, res) => {
// Destructuring username & password from body
const { username, password } = req.body;
// Checking if credentials match
if (username === userCredentials.username &&
password === userCredentials.password) {
//creating a access token
const accessToken = jwt.sign({
username: userCredentials.username,
email: userCredentials.email
}, process.env.ACCESS_TOKEN_SECRET, {
expiresIn: '10m'
});
// Creating refresh token not that expiry of refresh
//token is greater than the access token
const refreshToken = jwt.sign({
username: userCredentials.username,
}, process.env.REFRESH_TOKEN_SECRET, { expiresIn: '1d' });
// Assigning refresh token in http-only cookie
res.cookie('jwt', refreshToken, { httpOnly: true,
sameSite: 'None', secure: true,
maxAge: 24 * 60 * 60 * 1000 });
return res.json({ accessToken });
}
else {
// Return unauthorized error if credentials dont match
return res.status(406).json({
message: 'Invalid credentials' });
}
})
app.post('/refresh', (req, res) => {
if (req.cookies?.jwt) {
// Destructuring refreshToken from cookie
const refreshToken = req.cookies.jwt;
// Verifying refresh token
jwt.verify(refreshToken, process.env.REFRESH_TOKEN_SECRET,
(err, decoded) => {
if (err) {
// Wrong Refesh Token
return res.status(406).json({ message: 'Unauthorized' });
}
else {
// Correct token we send a new access token
const accessToken = jwt.sign({
username: userCredentials.username,
email: userCredentials.email
}, process.env.ACCESS_TOKEN_SECRET, {
expiresIn: '10m'
});
return res.json({ accessToken });
}
})
} else {
return res.status(406).json({ message: 'Unauthorized' });
}
})
app.listen(process.env.PORT, () => {
console.log(`Server active on http://localhost:${process.env.PORT}!`);
})
Publicación traducida automáticamente
Artículo escrito por GeeksforGeeks y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA