DEV Community

Tanzim Ibthesam
Tanzim Ibthesam

Posted on • Updated on

Laravel Api authentication (Sanctum) with NuxtJs(Part-2)

In the last part I mentioned about Api authentication with Laravel Sanctum if you didnt check it please check it out.
Here I will integrate it with Nuxt.js that is show you the frontend
Nuxt Installation
Here we are installing Nuxt as a seperate standalone frontend means you will install nuxt the way you do and integrate Laravel api with it.
npm init nuxt-app laravel-api-auth-sanctum so its npm init nuxt-app name of your project
Options
Javascript or Typescript
Imagedescription
We will be working with Javascript as of now.

Package manager-npm or yarn
Imagedescription

We will use npm you can use yarn
UI framework
Imagedescription
I am selecting Tailwind you can go for any.
Nuxt.js Modules
Imagedescription
You can select any I am going for Axios
Linting Tools
Imagedescription

I am going for Prettier
Testing Tools
Imagedescription
None for now
Rendering mode select SSR
Imagedescription
ServerHosting
Imagedescription
Here we will select NodeJS hosting
Development Tools
Imagedescription
Continous Integration
Imagedescription
It will be none
Version COntrol System
Imagedescription
Here I am selecting none.
Project Successfully Created

Imagedescription

PLease Carefully Note-The settings used in this project might differ based on clients requirement so based on requirements you need to adjust.
cd onto the project folder
npm run dev
If you have installed everything successfully
Imagedescription

Imagedescription

You will see this
pages/index.vue is the starting point of a Nuxt application.
Imagedescription

If you see the results you will see on localhost port 300 it gives you the thing
Imagedescription
In Compaonents folder you will keep all the compoanents here we will keep Navbar
Navbar.vue

  <div class=" flex justify-between items-center my-10">
    <nuxt-link to="/" class=" text-2xl font-semibold">
      Laranuxt Aut
    </nuxt-link>

    <!-- logo -->
    <nav class=" flex space-x-10">
      <nuxt-link
        class=" font-bold text-base uppercase"
        :to="{ name: 'auth-login' }"
        >Login</nuxt-link
      >
      <nuxt-link
        class=" font-bold text-base uppercase"
        :to="{ name: 'auth-register' }"
        >Register</nuxt-link
      >
    </nav>
  </div>
</template>
Enter fullscreen mode Exit fullscreen mode

In pages folder the components we create by default the name of the components will bue the route here we have created an auth folder inside pages folder and inside auth folder we have created 2 files one is login.vue and other is logout.vue
Imagedescription
If you go to http://localhost:3000/auth/login you can see the login route or if you go to http://localhost:3000/auth/register route you can see the register route.
Nuxt-link and named routes
When we include a component under page directory it becomes a route automatically. Like if we include fruits.vue under page folder and if we want to navigate to /fruits directory we can simply use

<nuxt-link
class=" font-bold text-base uppercase"
to="/fruits"
>Home</nuxt-link
>

Named Routes
If we want to include named routes we can write
<nuxt-link
class=" font-bold text-base uppercase"
:to="{ name: 'fruits' }"
>Home</nuxt-link
>

Point to be Noted-here if you change filename under pages folder to fruit.vue it will not work. Its a problem since if you use named routes in many locations you just also need to change link of the routes. But no need to worry.
Check .auth folder
In .nuxt folder there is router.js
Imagedescription You see there is a name,path and component it is automatically generated
Imagedescription
Here the routes are automatically generated here you must name your routes here.As a result if you change your component name continously in pages folder you dont need to change the nuxt-link if you link it to the named route.
Problem with Navbar
Here when we link to Login or registration routes we see no Navbar.

In project root directory create a layouts folder and inside that create layouts/default.vue
Go to laydefault.vue

  <div class=" max-w-6xl mx-auto">
    <Navbar />

    <main class="my-20">
      <Nuxt />
    </main>
  </div>
</template>
Enter fullscreen mode Exit fullscreen mode

Nav Link
Now when we go to registration or login routes we see the Navbar
Imagedescription
Connect Laravel Api with Nuxt
At first install axios
npm install @nuxtjs/axios
In nuxt.config.js
Imagedescription
Now comes the mainpart Register.vue


  <div class="container mx-auto sm:w-4/5 xl:w-1/4 border p-10 rounded-xl">
       <div class="text-center -mt-4">Register</div>

        <form action="" @submit.prevent="submitForm">
            <div class="md:w-1/2 space-y-3">
        <input type="email" v-model="form.email" class="px-6  border rounded-md" placeholder-gray-500 placeholder="Enter your email" /><br>
         <p class=" text-red-500 text-xs text-center" v-if="errors.email">
          {{ errors.email.join(" ") }}
        </p>
          <input type="text" v-model="form.username" class="px-6  border rounded-md" placeholder-gray-500 placeholder="Enter your username" /><br>
          <p class=" text-red-500 text-xs text-center" v-if="errors.username">
          {{ errors.username.join(" ") }}
        </p>
          <input type="password" v-model="form.password" class="px-6  border rounded-md" placeholder-gray-500 placeholder="Password" /><br>
          <p class=" text-red-500 text-xs text-center" v-if="errors.password">
          {{ errors.password.join(" ") }}
        </p>
          <input type="password" v-model="form.password_confirmation" class="px-6  border rounded-md" placeholder-gray-500 placeholder="Confirm your password" /><br>
          <p class=" text-red-500" v-if="errors.password_confirmation">
          {{ errors.password_confirmation.join(" ") }}
        </p>
          <button class="px-6  bg-green-300 text-white font-serif">SEND</button>
          </div>
        </form>
          <div class=""> Already have an account? <nuxt-link class="text-blue-600" :to="{name:'auth-login'}">Login</nuxt-link>
          </div>
      </div>

</template>

<script>
export default {
    data(){
        return{
            errors:{

            },
            form: {

        username: "",
        email: "",
        password: "",
        password_confirmation: ""
      }
        }

    },
    methods:{
       async submitForm(){
           this.errors='';
           try {
               const res= await this.$axios.$post("api/auth/register", this.form);
            //    console.log(res);
            console.log(res);
           } catch (error) {
               if(error.response.status===422){
                   this.errors = error?.response?.data?.errors;
               console.log(this.errors);

               }

           }


        }
    }

}
</script>

Enter fullscreen mode Exit fullscreen mode

Here there are many things if you dont know Vue or basics you might not understand. You can read through my VueJsBlogs for beginners.There are 7 blogs in total.

Here we have a registration form made with Tailwind and we are submitting http request through Axios. Then we are doing exception handling that is in case of any 422 errors
if(error.response.status===422){
this.errors = error?.response?.data?.errors;
console.log(this.errors);
}

In vue template
In case of any errors of email,password or username we set it like this
<p class="text-red-500 text-xs text-center" v-if="errors.email">
{{ errors.email.join(" ") }}
</p>

Imagedescription
This is the error you get. On the other hand when everything submitted successfully
Imagedescription
We can see on the console user registered successfully.
In Login.vue

<template>
  <div class="container mx-auto sm:w-4/5 xl:w-1/4 border p-10 rounded-xl">
       <div class="text-center -mt-4">Login</div>

      <div class="md:w-1/2 ">
             <form @submit.prevent="submitForm" action="" class="space-y-3">
        <input type="text" v-model="form.email"  class="px-6  border rounded-md" placeholder-gray-500 placeholder="Enter your email" /><br>

        <p class=" text-red-500 text-xs text-center" v-if="errors.email">
          {{ errors.email.join(" ") }}
        </p>
          <input type="password" v-model="form.password"  class="px-6  border rounded-md" placeholder-gray-500 placeholder="Enter your password" /><br>
          <p class=" text-red-500 text-xs text-center" v-if="errors.password">
          {{ errors.password.join(" ") }}
        </p>

          <button class="px-6 py-1 bg-yellow-300 text-white font-serif">SEND</button>
             </form>
          <div class="text-xs "> Not Registered? <nuxt-link class="text-blue-600" :to="{name:'auth-register'}">Register</nuxt-link></div>


  </div>
  </div>
</template>

<script>
// import swal from 'sweetalert2'
 export default {
   data(){
         return{
             errors:{

            },
            form: {


       email: "",
        password: "",
               }
        }

    },
    methods:{
       async submitForm() {
      this.errors = {};
      try {
         await this.$axios.$post("api/auth/login", this.form);
        });
        // this.$router.push({ name: "auth-login" });

      } catch (error) {
        if (error.response.status === 422) {
          this.errors = error?.response?.data?.errors;
          return;
        }
        // if (error.response.status === 401) {

      }
    }
  }
};
</script>
Enter fullscreen mode Exit fullscreen mode

Here we get all validation errors and if we enter correct usernaem and password we get the token
)
Here we see on the network tab we see we get the token This is taken from mozilla browser
Nuxt auth best way of handing tokens in Nuxt
Install Nuxt auth
npm install --save-exact @nuxtjs/auth-next
Also in nuxt.config.js
Imagedescription
You need to write some auth starteigies below axios in nuxt.config.js

Imagedescription
You will get these from nuxt-auth-docs. Remeber always read the docs you will find a lot of information.
Go back to Laravel project api.php
Imagedescription
Also include the user route in AuthController
Imagedescription
Testing auth/user route in Postman
Imagedescription
If token and everything is alright we get info of the current authenticated user.
Imagedescription
For this we need to create a ppropertly of adat of user in backend.
Create UserResource in Laravel
php artisan make:resource UserResource
Now if we go to AuthController
We need to change our user method

Testing in Postman
If everything is alright we get all user info as data object
Imagedescription
In Login.vue
We need to replace axios with loginWith since its the simpliest way of handling tokens.
Imagedescription
If we enter everything correctly and check out Vue Dev tools
on Chrome we will see an user object
Imagedescription
Below you can see
Imagedescription
In NavBar.vue if we want to see all details of current authenticated users
Imagedescription
If we check on the browser
Imagedescription
Showing logout while being authenticated
In Navbar.vue If user is not LoggedIn
Imagedescription
If User is LoggedIn
Imagedescription

While User is loggedIn in browser
Imagedescription
While User is logged out or not loggedin in browser
Imagedescription

So i guess thats very much it for Laravel Nuxt sanctum authentication as of now.

Discussion (4)

Collapse
musawershah1598 profile image
Musawer Shah

Hi whenever i try to make the post request to register route i am getting 419 status code. and the message says that csrf token mismatch. How can i fix it???

Collapse
tanzimibthesam profile image
Tanzim Ibthesam Author • Edited on

Are you facing the problem in postman? Did you write the register route properly?

Collapse
musawershah1598 profile image
Musawer Shah

No in postman it is working fine but in nuxt app it is causing problems on register route or simply any post request. Btw i had found a workaround don't know if it is correct or not. Here it is.



this.$axios.get("sanctum/csrf-cookie").then(()=>{
   // then after doing post request here it works.
})
Enter fullscreen mode Exit fullscreen mode
Thread Thread
tanzimibthesam profile image
Tanzim Ibthesam Author

Ok didnt face such issues anyways thanks will note it for future reference