Autenticación en React
La API del backend está lista para ser utilizada. Ahora vamos a añadir la autenticación en el lado del frontend.
Así es como se organiza la aplicación React:
- Al hacer clic en el botón Log in o Log out, la aplicación llama a las funciones definidas en
requests/auth.ts
para realizar consultas al servidor. - La información sobre el usuario actual se almacena en el componente raíz
App.tsx
bajo el nombrecurrentUser
. Si el usuario se ha conectado, este estado es de tipo{ id: number, name: string }
. En caso contrario, su valor esnull
. - Al iniciar la sesión, el servidor devuelve información sobre el usuario que se utiliza para establecer el estado
currentUser
. Al cerrar la sesión, la aplicación establece este estado comonull
.
Saber, en el lado del cliente, si un usuario está conectado y quién es, es útil para gestionar la visualización de los elementos de la interfaz de usuario. Esto nos permite, por ejemplo, saber qué botones de navegación deben ser visibles.
Abra el archivo requests/auth.ts
e implemente las funciones vacías.
import axios from 'axios';
import { ICredentials, IUser } from '../interfaces';
export async function logIn(credentials: ICredentials): Promise<IUser> {
const response = await axios.post<IUser>('/api/auth/login', credentials);
return response.data;
}
export async function logOut(): Promise<void> {
await axios.post('/api/auth/logout');
}
export async function signUp(credentials: ICredentials): Promise<IUser> {
const response = await axios.post<IUser>('/api/auth/signup', credentials);
return response.data;
}
Vaya a http://localhost:3000/login y conéctese. Debería ser redirigido a la página de inicio. Si hace clic en el botón Profile de la barra de navegación, debería ser llevado a su página personal. Puede añadir o eliminar publicaciones si lo desea.
Ahora vamos a actualizar la página. Se le redirige a la página de inicio de sesión como si hubiera cerrado la sesión. ¡Ay!
La razón de esto es que la aplicación del front-end ya no sabe que usted está conectado. Si mira el componente App
, verá que el estado currentUser
se inicializa a null
cuando se carga la aplicación. Así que tenemos que encontrar una manera de mantener el estado de inicio de sesión del usuario incluso si la página se actualiza.
Para ello, utilizaremos una cookie adicional para almacenar esta información que será legible por la aplicación front-end.
Abra el archivo api.controller.ts
y añada la opción userCookie
.
import { Context } from '@foal/core';
// ...
@UseSessions({
cookie: true,
user: fetchUser(User),
userCookie: (ctx: Context<User|undefined>) => ctx.user ? JSON.stringify({ id: ctx.user.id, name: ctx.user.name }) : '',
})
Esta opción establece una cookie adicional user
en el host del cliente con información sobre el usuario actual.
Ahora vuelva al archivo App.tsx
y añada la función getCurrentUserFromCookie
que aparece a continuación.
import * as cookie from 'cookie';
function getCurrentUserFromCookie(): IUser | null {
const userCookie = cookie.parse(document.cookie).user as string|undefined;
if (!userCookie) {
return null;
}
try {
return JSON.parse(userCookie);
} catch (error) {
return null;
}
}
export default function App() {
const [currentUser, setCurrentUser] = useState(getCurrentUserFromCookie());
// ...
}
Cuando la aplicación se carga, esta función comprobará si existe una cookie user
con información sobre el usuario actual. Si es así, su contenido se utilizará para establecer el valor de currentUser
.
Actualice la página. La aplicación ahora funciona como se esperaba.
También podría haber establecido una cookie del lado del cliente en la función
logIn
y eliminarla en la funciónlogOut
. Pero esta solución no funciona bien cuando el usuario se desconecta automáticamente después de un período de inactividad (expiración de la sesión).