Estoy construyendo un sitio web de comercio electrónico listo para producción donde cualquier proveedor local puede cargar sus productos y venderlos directamente a los clientes.
Estoy usando Firebase para autenticarme con Gmail y números de teléfono. Mi front-end puede verificar si el usuario está autenticado o no. ¿Cómo puedo verificar en el backend si el usuario está autenticado o no?
Digamos que algunas rutas están protegidas en el lado del cliente y solo los usuarios autenticados pueden acceder a ellas. ¿Qué pasa si alguien usa say (cartero) y usa esas rutas? ¿De todos modos puedo adjuntar mi token jwt y el cliente solo lo obtendrá si se autentica con su gmail o teléfono?
const signIn = () => { return signInWithPopup(auth, provider) .then((result) => { // This gives you a Google Access Token. You can use it to access the Google API. const credential = GoogleAuthProvider.credentialFromResult(result); const token = credential.accessToken; console.log(token); // The signed-in user info. const user = result.user; console.log("credential:", credential, "token:", token, "user:", user); }) .catch((error) => { // Handle Errors here. const errorCode = error.code; const errorMessage = error.message; // The email of the user's account used. const email = error.email; // The AuthCredential type that was used. const credential = GoogleAuthProvider.credentialFromError(error); console.log(errorCode, errorMessage, credential, email); // ... }); };Esto autentica si el usuario con gmail. ¿Cómo puedo usar esto para decirle a mi backend que este tipo está autenticado, y aquí está su identificación única y otra información?
Express le permite usar middlewares. Los middlewares son bastante simples: alguna lógica que se ejecutará durante el cumplimiento de una solicitud, y puede configurar cuándo ejecutar esa lógica y sobre qué ejecutarla.
Un middleware de autorización le brindará la funcionalidad exacta que está buscando. Te daré un ejemplo:
async function firebaseIdTokenValidationMiddleware(req, res, next) { //First, I'll check if the request has the Authorization header and if it contains a Bearer type token if ( req.headers.authorization && req.headers.authorization.startsWith('Bearer ') ) { //If the reuqest has a token, I'll read it const idToken = req.headers.authorization.split('Bearer ')[1]; if (idToken) { try { //And I'll use Firebase Auth API to validate the token const decodedIdToken = await auth().verifyIdToken(idToken); if (decodedIdToken) { //If Firebase validates the token, the middleware can allow the next step req.authEntity = decodedIdToken; return next(); } } //Otherwise, we answer with a "Forbidden" status code return res.status(403).json({}); } } //If there is no authorization header, we answer with a "Unauthorized" status code return res.status(401).json({}); }Obviamente, puedes personalizar los códigos de error. Toda la magia se delega a la API de autenticación de Firebase:
auth().verifyIdToken(MY_TOKEN)Esta llamada verifica si Firebase Auth emitió el token dado y si es válido (por ejemplo, verifica si el token está vencido o no). Después de esta verificación, en mi ejemplo guardo la entidad decodificada en la solicitud:
req.authEntity = decodedIdToken;Es muy útil si necesita acceder a esa información en el enrutador de su terminal. Puede visitar esta página para obtener la referencia completa de lo que le brinda la API de Firebase después de la validación.
Tenga en cuenta que auth().verifyIdToken() está en la API de administración, por lo que debe importarlo en su proyecto.
Todo lo que hicimos hasta ahora fue simplemente crear el middleware. Aún tendrá que decirle a Express que lo use. Puedes hacerlo de dos maneras.
Especificándolo en el enrutador único:
app.get('/', firebaseIdTokenValidationMiddleware, async(req,res) => { //YOUR LOGIC }Globalmente, y se llama middleware de nivel de aplicación:
app.use(firebaseIdTokenValidationMiddleware);