quasar-app-extension-rt-vueauth
v0.1.9
Published
A Quasar Project
Readme
Quasar App Extension rt-auth
Una extensión de Quasar que proporciona soluciones de autenticación modular para tus aplicaciones, permitiendo integrar fácilmente diferentes proveedores de autenticación como Firebase, Passport, Sanctum, Strapi y Supabase.
Esta extensión simplifica la gestión de usuarios, tokens, rutas protegidas y flujos de autenticación (login, registro, logout, reseteo de contraseña) en tu proyecto Quasar.
Características Principales
- Modularidad: Cambia fácilmente entre diferentes proveedores de autenticación sin reescribir gran parte de tu código.
- Gestión de Estado: Integración con Pinia para una gestión centralizada y reactiva del estado de autenticación (usuario, token).
- Rutas Protegidas: Guardias de navegación para proteger rutas que requieren autenticación o que solo deben ser accesibles para usuarios no autenticados.
- Composables Dedicados: Composables específicos para cada proveedor que encapsulan la lógica de autenticación, facilitando su uso en componentes Vue.
- Persistencia de Sesión: Soporte para persistencia de sesión a través de
SessionStorage(configurable). - Validaciones Centralizadas: Reglas de validación reutilizables para formularios de autenticación.
Proveedores de Autenticación Soportados
- Firebase
- Passport (Basado en Token JWT)
- Sanctum
- Strapi
- Supabase
Requisitos
- Plugin de Quasar
Cookiesactivo. - Plugin de Quasar
SessionStorageactivo (para persistencia de sesión). - Pinia instalado y configurado en tu proyecto Quasar.
Instalación
Para instalar esta extensión en tu proyecto Quasar:
quasar ext add rt-vueauthQuasar CLI descargará la extensión desde el registro de NPM y la instalará en tu proyecto.
Prompts (Preguntas durante la instalación)
Durante la instalación, se te preguntará qué proveedor de autenticación deseas utilizar. Tu elección determinará qué archivos específicos del proveedor se copiarán en tu proyecto.
Configuración y Uso (Ejemplo con Passport)
Una vez instalado, la extensión copiará los archivos necesarios en tu directorio src/.
Estructura de Archivos Clave (para Passport)
src/stores/auth.js: Store de Pinia para gestionar el estado de autenticación (token, usuario).src/auth/requests.js: Funciones para interactuar con tu API de autenticación (login, registro, etc.).src/auth/composables/: Composables de Vue para usar la lógica de autenticación en tus componentes.src/auth/boot/authProvidersBoot.js: Archivo de arranque que registra las rutas de autenticación.src/boot/auth.js: Archivo de arranque principal que configura los guardias de navegación.src/config/passport.js: Archivo de configuración para los endpoints de la API de Passport.src/lib/validations/auth.js: Archivo con reglas de validación centralizadas.
Validaciones Centralizadas
El archivo src/lib/validations/auth.js exporta un conjunto de reglas de validación que puedes usar directamente en tus q-input de Quasar. Estas reglas también son utilizadas internamente por los composables para determinar la validez del formulario.
Ejemplo de uso en un q-input:
import { emailRules, passwordRules } from 'src/lib/validations/auth';
// En tu template
<q-input
v-model="form.email"
label="Email"
:rules="emailRules"
/>
<q-input
v-model="form.password"
label="Password"
type="password"
:rules="passwordRules"
/>Uso del Store de Pinia
El store de Pinia (src/stores/auth.js) es el centro de la gestión de autenticación. Puedes acceder a él en cualquier componente o composable:
import { useAuthStore } from 'stores/auth';
const authStore = useAuthStore();
// Acceder al estado
console.log(authStore.isAuthenticated);
console.log(authStore.currentUser);
// Llamar a acciones
await authStore.login({ email: '[email protected]', password: 'password' });
authStore.logout();Uso de Composables (Ejemplo con Passport)
Los composables (src/auth/composables/) te permiten integrar fácilmente la lógica de autenticación en tus componentes Vue.
useLogin.js
// En tu componente Vue (ej. LoginCard.vue)
import { ref } from 'vue';
import useLogin from 'src/auth/composables/useLogin';
export default {
setup() {
const { form, loading, validationErrors, login, resetErrors, isFormValid } = useLogin();
const email = ref('');
const password = ref('');
const handleLogin = async () => {
resetErrors();
form.email = email.value;
form.password = password.value;
await login();
};
return {
email,
password,
form,
loading,
validationErrors,
handleLogin,
isFormValid, // Usar para deshabilitar el botón
};
},
};useRegister.js
// En tu componente Vue (ej. RegisterCard.vue)
import { ref } from 'vue';
import useRegister from 'src/auth/composables/useRegister';
export default {
setup() {
const { form, loading, validationErrors, register, resetErrors, isFormValid } = useRegister();
const name = ref('');
const email = ref('');
const password = ref('');
const passwordConfirmation = ref('');
const handleRegister = async () => {
resetErrors();
form.name = name.value;
form.email = email.value;
form.password = password.value;
form.password_confirmation = passwordConfirmation.value;
await register();
};
return {
name,
email,
password,
passwordConfirmation,
form,
loading,
validationErrors,
handleRegister,
isFormValid, // Usar para deshabilitar el botón
};
},
};useLogout.js
// En tu componente Vue (ej. LogoutButton.vue)
import useLogout from 'src/auth/composables/useLogout';
export default {
setup() {
const { logout } = useLogout();
return { logout };
},
};Endpoints de API Esperados (para Passport)
Tu backend de Passport debe exponer los siguientes endpoints para que la extensión funcione correctamente:
POST /api/login: Para iniciar sesión. Esperaemailypassword. Retorna unaccess_token(string JWT) y datos deluser(objeto).POST /api/register: Para registrar un nuevo usuario. Esperaname,email,password,password_confirmation. Retorna unaccess_token(string JWT) y datos deluser(objeto).POST /api/logout: Para cerrar sesión (invalida el token en el backend).GET /api/user: Para obtener los datos del usuario autenticado.POST /api/forgot-password: Para solicitar un reseteo de contraseña. Esperaemail.POST /api/reset-password: Para resetear la contraseña. Esperaemail,token(del email de reseteo),password,password_confirmation.POST /api/user/password: Para cambiar la contraseña de un usuario autenticado. Esperacurrent_password,password,password_confirmation.
Asegúrate de que tu variable de entorno process.env.VUE_API apunte a la URL base de tu API.
Desinstalación
Para desinstalar la extensión:
quasar ext remove rt-vueauthPruebas Unitarias
La extensión incluye pruebas unitarias para la lógica central del store de Pinia de Passport, asegurando la fiabilidad de la gestión de autenticación.
Configuración de Pruebas
Las pruebas están configuradas con Vitest y se ejecutan en un entorno happy-dom para simular un navegador. Se utilizan mocks para aislar el store de las llamadas reales a la API (src/auth/requests) y del SessionStorage de Quasar, permitiendo probar la lógica interna de forma controlada.
Casos de Prueba
El archivo test/passport.store.spec.js contiene los siguientes casos de prueba:
login successfully fetches and stores token and user:- Verifica que la acción
logindelstorellama correctamente a la API de login, guarda el token recibido en el estado de Pinia y enSessionStorage, y luego llama afetchUserpara obtener y almacenar los datos del usuario.
- Verifica que la acción
logout clears token, user, and session storage:- Asegura que la acción
logoutllama a la API de logout y, crucialmente, limpia el token y los datos del usuario del estado de Pinia y deSessionStorage, dejando al usuario como no autenticado.
- Asegura que la acción
fetchUser clears session if API call fails:- Prueba que si la llamada a
fetchUserfalla (por ejemplo, debido a un token inválido o caducado), elstorelimpia automáticamente la sesión, desautenticando al usuario.
- Prueba que si la llamada a
initial state is hydrated from SessionStorage:- Verifica que al inicializar el
store, este intenta recuperar el token deSessionStorage, permitiendo la persistencia de la sesión entre recargas de página.
- Verifica que al inicializar el
Puedes ejecutar las pruebas con:
npm run test:unit