So I am making a user validation system for my application, but I can´t validate a token if I can´t obtain it from the cookies in my browser. The thing is the cookies don´t seem to be appearing there.
import { getConnection } from '../database/connection.js';
import createAccessToken from '../libs/jwt.js';
import { queriesUsers } from '../database/queries.js';
import { serialize } from 'cookie';
export const loginController = async (req, res) => {
try {
const { username, password } = req.body;
const pool = await getConnection();
const result = await pool
.request()
.input("username", username)
.input("password", password)
.query(queriesUsers.validateUser);
const user = result.recordset[0];
if (user && user.Type === 'S') {
const token = createAccessToken(user);
if (token) {
console.log(token)
res.cookie("Token", token, {
httpOnly: true,
maxAge: 600000,
});
console.log("cookies", req.cookies);
res.status(200).json({token});
} else {
res.status(500).json({ error: "Error"});
}
} else {
res.status(401).json({ error: 'Credenciales inválidas' });
}
} catch (error) {
console.error("Error al validar el usuario:", error);
res.status(500).json({ error: "Error al validar el usuario" });
}
};
This is my log in controller (for more context, this application does not have a register controller only a log in controller). When I console log the cookies I just obtain this anwer:
cookies [Object: null prototype] {}
This is how it looks in the browser
Does anyone know why aren´t the cookies appearing on my browser? If you need to see more of my code just let me know.
Here is the frontend that executes the controller:
import React, { useState, useContext } from 'react';
import styles from '../styles/login.module.css';
import { useNavigate } from 'react-router-dom';
import { AuthContext } from '../context/AuthContext';
const Login = () => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const navigate = useNavigate();
const { login } = useContext(AuthContext);
const handleUsernameChange = (event) => {
setUsername(event.target.value);
};
const handlePasswordChange = (event) => {
setPassword(event.target.value);
};
const handleSubmit = async (event) => {
event.preventDefault();
try {
await login(username, password);
} catch (error) {
if (error.response) {
setError('Error al iniciar sesión. Verifica tus credenciales.');
} else {
setError('Error de conexión. Inténtalo nuevamente más tarde.');
}
}
setPassword('');
setUsername('');
};
return (
<div className={styles.main}>
<div className={styles.descriptionContainer}>
<img className={styles.logo} src="/biconlogo - copia.png" alt="bicon" />
<h2 className={styles.subtitle}>¡Bienvenido!</h2>
<p className={`${styles.descriptionText} ${styles.paragraph}`}>
<b>BiCon Survey</b> es una solución que permite a los colaboradores
identificar las actividades que se realizan y asignarles un peso que
refleje la intensidad con la que ejecutan. La información recabada
será de utilidad para el Modelo de Costeo Basado en Actividades.
</p>
</div>
<div className={styles.login}>
<h2 className={styles.loginH2}>Iniciar sesión</h2>
{error && <p className={styles.error}>{error}</p>}
<form className={styles.loginForm} onSubmit={handleSubmit}>
<div>
<label className={styles.loginLabel} htmlFor="username">
Usuario:
</label>
<input
className={styles.loginInput}
value={username}
onChange={handleUsernameChange}
/>
</div>
<div>
<label className={styles.loginLabel} htmlFor="password">
Contraseña:
</label>
<input
type="password"
className={styles.loginInput}
value={password}
onChange={handlePasswordChange}
/>
</div>
<button type="submit" className={styles.loginButton}>
Iniciar sesión
</button>
</form>
</div>
</div>
)
}
export default Login;
And here is the user context (AuthContext):
import { createContext, useState, useContext } from "react";
import axios from 'axios';
export const AuthContext = createContext();
export const useAuth = () => {
const context = useContext(AuthContext);
if (!context) {
throw new Error("useAuth must be within AuthProvider");
}
return context;
}
export const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null);
const [token, setToken] = useState(null);
const [isAuthenticated, setIsAuthenticated] = useState(false);
const [errors, setErrors] = useState([]);
const login = async (username, password) => {
try {
const response = await axios.post('http://localhost:4000/api/login', {
username: username,
password: password,
});
const authToken = response.data.token;
console.log(authToken)
setUser({ ...response.data.user, token: authToken });
setToken(authToken);
setIsAuthenticated(true);
setErrors([]);
} catch (error) {
setErrors(error.response.data);
}
}
const logout = () => {
setUser(null);
setToken(null);
setIsAuthenticated(false);
setErrors([]);
}
return (
<AuthContext.Provider value={{
user,
token,
isAuthenticated,
errors,
login,
logout,
}}>
{children}
</AuthContext.Provider>
)
}
2
Answers
In the axios request add withCredentials: true :
on the app add cors configuration like this:
Did you make sure to check your browser to see if it enables cookies?