0

I am developing a NextJs app with a Laravel backend. I chose to go with Token based authentication. Logging in and fetching user data via Postman is working fine. But it's only returning 401 Unauthorized on the NextJs app for fetching user data even though logging in is fine.

I used this https://github.com/laravel/breeze-next as an example. I implemented the same as it has.

This is the error message that I received on console log. GET http://localhost:8000/api/v1/auth-user 401 (Unauthorized)

CODES

axios.js

import Axios from 'axios';

const axios = Axios.create({
  baseURL: process.env.NEXT_PUBLIC_BACKEND_URL,
  headers: {
    'X-Requested-With': 'XMLHttpRequest',
  },
  withCredentials: true,
});

export default axios;

useAuth.js

import useSWR from 'swr';
import axios from '../lib/axios';
import { useEffect } from 'react';
import { useRouter } from 'next/router';

export const useAuth = ({ middleware, redirectIfAuthenticated } = {}) => {
  const router = useRouter();

  const {
    data: user,
    error,
    mutate,
  } = useSWR('/api/v1/auth-user', () =>
    axios
      .get('/api/v1/auth-user')
      .then((res) => res.data)
      .catch((error) => {
        if (error.response.status !== 409) throw error;

        router.push('/verify-email');
      })
  );

  const csrf = () => axios.get('/sanctum/csrf-cookie');

  const register = async ({ setErrors, ...props }) => {
    await csrf();

    setErrors([]);

    axios
      .post('/register', props)
      .then(() => mutate())
      .catch((error) => {
        if (error.response.status !== 422) throw error;

        setErrors(error.response.data.errors);
      });
  };

  const login = async ({ setErrors, setStatus, ...props }) => {
    await csrf();

    setErrors([]);
    setStatus(null);

    axios
      .post('/login', props)
      .then(() => mutate())
      .catch((error) => {
        if (error.response.status !== 422) throw error;

        setErrors(error.response.data.errors);
      });
  };

  const forgotPassword = async ({ setErrors, setStatus, email }) => {
    await csrf();

    setErrors([]);
    setStatus(null);

    axios
      .post('/forgot-password', { email })
      .then((response) => setStatus(response.data.status))
      .catch((error) => {
        if (error.response.status !== 422) throw error;

        setErrors(error.response.data.errors);
      });
  };

  const resetPassword = async ({ setErrors, setStatus, ...props }) => {
    await csrf();

    setErrors([]);
    setStatus(null);

    axios
      .post('/reset-password', { token: router.query.token, ...props })
      .then((response) =>
        router.push('/login?reset=' + btoa(response.data.status))
      )
      .catch((error) => {
        if (error.response.status !== 422) throw error;

        setErrors(error.response.data.errors);
      });
  };

  const resendEmailVerification = ({ setStatus }) => {
    axios
      .post('/email/verification-notification')
      .then((response) => setStatus(response.data.status));
  };

  const logout = async () => {
    if (!error) {
      await axios.post('/logout').then(() => mutate());
    }

    window.location.pathname = '/login';
  };

  useEffect(() => {
    if (middleware === 'guest' && redirectIfAuthenticated && user)
      router.push(redirectIfAuthenticated);
    if (window.location.pathname === '/verify-email' && user?.email_verified_at)
      router.push(redirectIfAuthenticated);
    if (middleware === 'auth' && error) logout();
  }, [user, error]);

  return {
    user,
    register,
    login,
    forgotPassword,
    resetPassword,
    resendEmailVerification,
    logout,
  };
};

login.js

import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
import { useAuth } from '../hooks/useAuth';

const LoginScreen = () => {
  const [email, setEmail] = useState(null);
  const [password, setPassword] = useState(null);
  const [shouldRemember, setShouldRemember] = useState(false);
  const [errors, setErrors] = useState([]);
  const [status, setStatus] = useState(null);

  const router = useRouter();

  const { login, user } = useAuth({
    middleware: 'guest',
    redirectIfAuthenticated: '/',
  });

  useEffect(() => {
    if (router.query.reset?.length > 0 && errors.length === 0) {
      setStatus(atob(router.query.reset));
    } else {
      setStatus(null);
    }
  }, [errors, router]);

  const submitHandler = (e) => {
    e.preventDefault();

    login({ email, password, remember: shouldRemember, setErrors, setStatus });

    console.log(email, password);
  };

  return (
    <div>
      <form onSubmit={submitHandler}>
        <input type="email" onChange={(e) => setEmail(e.target.value)} />
        <br />
        <input type="password" onChange={(e) => setPassword(e.target.value)} />
        <br />
        <button type="submit">Sign In</button>
      </form>
    </div>
  );
};

export default LoginScreen;
N69S
  • 16,110
  • 3
  • 22
  • 36
Frank
  • 321
  • 1
  • 3
  • 11

0 Answers0