Estoy usando AWS amplificar para la autenticación de usuarios en mi aplicación React front-end. La aplicación My React se comunica directamente con amplificar sin ninguna interacción de back-end (servidor de nodo).
Tengo una API REST escrita en node/express. Quiero asegurar esa API usando amplificar.
Actualmente, planeo pasar el token de acceso de mi aplicación de reacción a mi servidor de nodo. Pero no puedo encontrar una forma de verificar este token en el backend usando amplificar.
¿El paquete aws-amplify proporciona alguna función en la que pueda pasar el token de acceso para verificarlo?
Algo así como Auth.verifyToken(<access_token>)
Desafortunadamente, no existe tal método disponible en el SDK oficial de aws-amplify. Después de investigar mucho, tuve que escribir mi propio middleware para eso. Esto no es tan difícil como parece, pero la única parte difícil es recopilar la información correcta de la enorme documentación de AWS.
He escrito este middleware para lograr lo mismo, espero que esto ayude
import axios from 'axios' import awsconfig from '../../aws-exports'; const COGNITO_URL = `https://cognito-idp.${awsconfig.aws_project_region}.amazonaws.com/`; const authentication = async (req, res, next) => { try { const accessToken = req.headers.authorization.split(" ")[1]; const { data } = await axios.post( COGNITO_URL, { AccessToken: accessToken }, { headers: { "Content-Type": "application/x-amz-json-1.1", "X-Amz-Target": "AWSCognitoIdentityProviderService.GetUser" } } ) req.user = data; next(); } catch (error) { return res.status(401).json({ message: 'Auth failed' }); } }; export default authentication;Este middleware toma el encabezado de autorización y verifica el token de acceso entrante mediante la API REST de AWS Cognito.
Para obtener accessToken en su front-end, puede hacer algo como esto:
const { accessToken: { jwtToken } } = await Auth.currentSession(); Este jwtToken es su token de acceso, puede enviarlo en su encabezado de Authorization y luego verificarlo en el backend usando el middleware que he escrito.
AWS en realidad tiene esto bastante bien documentado. Escribí una esencia en un middleware que escribí para validar los tokens de AWS Cognito en mi servidor express.js.
Básicamente, cuando crea un grupo de usuarios en Amazon, AWS crea una clave web JSON (JWK). El JWT contiene una clave pública que puede usar para verificar la firma de un JWT.
A un alto nivel en Javascript:
import jwt from "jsonwebtoken"; const authToken = getJwtFromHeader(request); // please remember to verify the "iss" claim and "exp" claim! validateAuthToken(authToken); // convert a jwk to a PEM for use by OpenSSL or crypto const jwk = getJwkFromAWS(); const pem = jwkToPem(jwk); // verify the signature of the token using the public key from AWS await jwt.verify(authToken, pem, {algorithms: ['RS256']}, (err, decoded) =>{ console.log('decoded', decoded); // TODO -- verify claims from decoded token });Mi GIST para una implementación completa de express.js: https://gist.github.com/fourgates/92dc769468497863168417c3524e24dd
Recursos de AWS:
https://github.com/awslabs/aws-support-tools/tree/master/Cognito/decode-verify-jwt https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user -grupos-usando-tokens-verificando-un-jwt.html
Desafortunadamente, el SDK de aws-amplify no proporciona esa funcionalidad. Por esa razón, he creado un paquete npm para manejarlo.
El paquete expone:
authenticate : un middleware Express que se puede agregar a cualquier ruta que deba autenticarse en un grupo de usuarios de Cognito.authenticationError : un controlador de errores Express que se encarga de los errores de autenticación generados por el middleware de authenticate .JWTValidator : una clase que se puede instanciar para validar los JWT emitidos por Cognito. Esto es útil si necesita una autenticación personalizada y una lógica de manejo de errores. El middleware de authenticate lo usa internamente. // app.js 'use strict'; const express = require('express'); const { authenticate, authenticationError } = require('aws-cognito-express'); const app = express(); // Add the authentication middleware. app.use(authenticate({ region: 'us-east-2', userPoolId: 'us-east-2_6IfDT7ZUq', tokenUse: ['id', 'access'], audience: ['55plsi2cl0o267lfusmgaf67pf'] })); // Protected route. app.get('/articles', (req, res, next) => { console.log('JWT payload: ', req.cognito); }); // Add the authentication error handler. app.use(authenticationError()); module.exports = app;Para casos de uso más avanzados, consulte los documentos aquí .