skip to Main Content

It is my first time using useQuery and I don’t even know even if the problem is useQuery related or not but I am having trouble with setting Cookie for further user interactions.

Login function starts in a LoginForm.tsx which uses useForm()

  const { mutate: login, isLoading } = useLoginMutation();

  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<LoginInputType>();


  function onSubmit({ email, password, remember_me }: LoginInputType) {
    login({
      email,
      password,
      remember_me,
    });
    console.log(email, password, remember_me, 'data');
  }

this is use-login.tsx where useLoginMutation exists. useLoginMutation runs login function.

async function login(input: LoginInputType) {
  return http.post(API_ENDPOINTS.LOGIN, input);
}

export const useLoginMutation = () => {
  const { authorize, closeModal } = useUI();
  return useMutation((input: LoginInputType) => login(input), {
    onSuccess: (data: any) => {
      console.log(data); //undefined
      Cookies.set('auth_token', data.token);
      authorize();
      closeModal();
    },
    onError: (data) => {
      console.log(data, 'login error response');
    },
  });
};

Here is the http function which login() uses

const http = axios.create({
  baseURL: process.env.NEXT_PUBLIC_REST_API_ENDPOINT,
  timeout: 30000,
  headers: {
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
});

// Change request data/error here
http.interceptors.request.use(
  (config) => {
    const token = getToken();
    console.log(token + ' from http.ts');
    config.headers = {
      ...config.headers,
      Authorization: `Bearer ${token ? token : ''}`,
    };
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);


 //this is getToken() which I imported
export const getToken = () => {
  if (typeof window === undefined) {
    return null;
  }
  return Cookies.get('auth_token');
};

Since my frontend uses cookies I set cokies for my backend as well

userController.js

exports.login = asyncHandler(async (req, res, next) => {
  const user = await User.findOne({ email: req.body.email });

  if (!user || !(await bcrypt.compare(req.body.password, user.password))) {
    return next(new ApiError('Incorrect email or password', 401));
  }
  // 3) generate token
  const token = await createToken(user._id);

  // Delete password from response
  delete user._doc.password;

  // 4) set cookie
  res.cookie('auth_token', token, {
    httpOnly: true,
    maxAge: 72 * 60 * 60 * 1000,
  });

  // 5) send response to client side
  res.status(200).json({ data: user, token });
});

When I run login from postman I can see user object and Bearer Token and I can use other user function which want autherization. I can see them when I login from front end as well and I can see SetHeader in response on Network tab too but my I cant set cookie for frontend . Console.logs won’t log response data and cookie wont be set properly. I tried and could not react returned object at all. I feel like I am missing something very fundemantal and basic but can’t figure it out.

2

Answers


  1. Chosen as BEST ANSWER

    well, changin login() function solve the problem.

    async function login(input: LoginInputType) {
      const { data } = await http.post(API_ENDPOINTS.LOGIN, input);
      return data;
    }
    

  2. It seems that you are confusing how cookies work when they are set to httpOnly. There is no need to manually set the auth_token on the client-side when you are setting the cookie within the server to be httpOnly. Indeed, it is impossible to do so as httpOnly cookies cannot be accessed by JavaScript by design.

    The only thing you need to do on the client-side is ensure that the cookie is included in all future requests. In order to do this using axios you need to include the withCredentials: true option: https://axios-http.com/docs/req_config.

    P.S. You will also likely need to include other options on the server when setting the cookie as httpOnly, e.g. secure: true and domain: .example.com.

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