# 5.- Creando nuestro Frontend con Next Js

WARNING

Para la parte del frontend clonaremos el repositorio ya creado y listo que realizo laravel

Clonar repositorio (opens new window)

  • En la carpeta clonada encontraremos un archivo .env.example que tendremos que cambiar de nombre a .env.local

  • Ahora que ya tenemos el repositorio tenemos que verificar si podemos registrar un usuario y realizar también un login correctamente

Al momento de realizar login correctamente el backend nos tienen que enviar el userName y el token.

Nos dirigimos al archivo 'src/hooks/auth.js' para agregar unas modificaciones para mirar los datos enviados desde el backend por la consola del navegador.

  • Vamos a la parte de la función del login y modificamos
  //Antes
    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)
            })
    }

    //Ahora
    const login = async ({ setErrors, setStatus, ...props }) => {
        await csrf()
        setErrors([])
        setStatus(null)
        axios
            .post('/login', props)
            .then((res) => {
                console.log('login', res.data.data.token)
                mutate()
                return res
            })
            .catch(error => {
                if (error.response.status !== 422) throw error
                setErrors(error.response.data.errors)
            })
    }
  • Si queremos ver los datos del usuario logeado realicemos lo siguiente:
    //Antes
    const { data: user, error, mutate } = useSWR('/api/user', () =>
        axios
            .get('/api/user')
            .then(res => res.data)
            .catch(error => {
                if (error.response.status !== 409) throw error
                router.push('/verify-email')
            }),
    )
    //Ahora
    const { data: user, error, mutate } = useSWR('/api/user', () =>
        axios
            .get('/api/user')
            .then(res => {
                console.log(res.data)
                return res.data
            })
            .catch(error => {
                if (error.response.status !== 409) throw error

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

# Creando función para cookies

Para esto tenemos que agregar una función tanto para guardar, leer, y eliminar cookies y lo realizamos en el archivo auth.js para así poder utilizar la función en cualquier momento que se requiera.

    //cookies save
    const setCookie = (key, value) => {
      if (getCookie('name') == null) {
      document.cookie = key +'='+ value +'; Path=/;';
      }
      if (getCookie('token') == null) {
      document.cookie = key +'='+ value +'; Path=/;';
      }
    }
    //cookie getdata
    function getCookie(name) {
      var value = '; ' + document.cookie
      var parts = value.split('; ' + name + '=')
      if (parts.length >= 2) return parts.pop().split(';').shift()
    }
    //cookie delete
    const deleteCookie = name => {
      if(getCookie('name')){
          document.cookie = name +'=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;';
      }
      if(getCookie('token') ){
          document.cookie = name +'=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;';
      }
    }

Ya tenemos las funciones para almacenar y eliminar el token de las cookies ahora toca utilizar la función para poder guardar los datos cuando realizamos el login y eliminar los datos de las cookies cuando el usuario hace logout.

# Guardando en las cookies el token y el user

    //capturando las respuestas
    const name = res.data.data.name
		const token = res.data.data.token
		setCookie('name', name)
    setCookie('token', token)

# Eliminando las cookies al hacer logout

    //Delete Cookies token and username
    deleteCookie('name')
    deleteCookie('token')

# Utilizando las funciones de las cookies en otras páginas

Para eso tenemos que ir al final del archivo auth.js y en return colocar las funciones que queremos utilizar más adelante

    return {
      user,
      register,
      login,
      forgotPassword,
      resetPassword,
      resendEmailVerification,
      logout,
      //cookie 
      setCookie,
      getCookie,
      deleteCookie,
    }

# Rutas protegidas con Token

  • Para proteger algunas rutas necesitamos en la parte backend utilizar el middleware que nos brinda sanctum.

Si queremos proteger algunas rutas necesitamos desde el frontend enviar el token que se almacena en las cookies, pero antes en el archivo api.php utilicemos Route::group() y dentro colocamos las rutas que queremos proteger

  • Backend
    //Backend
    Route::group(['middleware' => 'auth:sanctum'], function(){
        Route::get('/articles', [ArticleController::class, 'index']);
    });
  • Frontend

En la parte del frontend como ya almacenamos el token el las cookies ahora tenemos que enviar ese token al momento de realizar una petición al lado del servidor.

Para eso con la función que se creÓ en el archivo auth.php la importamos en dashboard.js ejemplo:

  import { useAuth } from '@/hooks/auth'
  const Dashboard = () => {
    const { getCookie } = useAuth()
    const token = getCookie('token')
  }

   useEffect(() => {
        getFilms()
    }, [])

    async function getFilms() {
        const response = await axios.get(
            `${process.env.NEXT_PUBLIC_BACKEND_URL}/api/articles`, 
            { 
              //Enviando la cookie del usuario logeado para traer los articulos
              headers: { "Authorization": `Bearer ${token}` } 
            })
        const data = response.data.articles.data
        console.log(data)
    }

Si no enviamos el token de usuario logeado nos dará un error 401 (Unauthorized)

  • Otros errores
    Si nos da un error Server Error ReferenceError: document is not defined
    if (typeof window !== 'undefined') {
        var token = getCookie('token')
    }
  • Al enviar el token en cada petición podemos capturar al user logeado para realizar validaciones.
    $user = auth()->user()->id;
    $users = Auth()->user();

Cookies and axios get, post, put, etc (opens new window)