skip to Main Content

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


  1. Chosen as BEST ANSWER

    In the axios request add withCredentials: true :

    const response = await axios.post('http://localhost:4000/api/login', {
            username: username,
            password: password,
          }, {
            withCredentials: true, 
          });
    

    on the app add cors configuration like this:

    // Use cors
    app.use(cors({
        origin: 'http://localhost:3000',
        credentials: true, // Enable credentials (cookies)
    }));
    

  2. Did you make sure to check your browser to see if it enables cookies?

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search