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
We will be working with Javascript as of now.
We will use npm you can use yarn
UI framework
I am selecting Tailwind you can go for any.
Nuxt.js Modules
You can select any I am going for Axios
Linting Tools
I am going for Prettier
Testing Tools
None for now
Rendering mode select SSR
ServerHosting
Here we will select NodeJS hosting
Development Tools
Continous Integration
It will be none
Version COntrol System
Here I am selecting none.
Project Successfully Created
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
You will see this
pages/index.vue is the starting point of a Nuxt application.
If you see the results you will see on localhost port 300 it gives you the thing
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>
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
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
You see there is a name,path and component it is automatically generated
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>
Nav Link
Now when we go to registration or login routes we see the Navbar
Connect Laravel Api with Nuxt
At first install axios
npm install @nuxtjs/axios
In nuxt.config.js
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>
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>
This is the error you get. On the other hand when everything submitted successfully
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>
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
You need to write some auth starteigies below axios in nuxt.config.js
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
Also include the user route in AuthController
Testing auth/user route in Postman
If token and everything is alright we get info of the current authenticated user.
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
In Login.vue
We need to replace axios with loginWith since its the simpliest way of handling tokens.
If we enter everything correctly and check out Vue Dev tools
on Chrome
we will see an user object
Below you can see
In NavBar.vue
if we want to see all details of current authenticated users
If we check on the browser
Showing logout while being authenticated
In Navbar.vue
If user is not LoggedIn
If User is LoggedIn
While User is loggedIn in browser
While User is logged out or not loggedin in browser
So i guess thats very much it for Laravel Nuxt sanctum authentication as of now.
Top comments (7)
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???
Are you facing the problem in postman? Did you write the register route properly?
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.
Ok didnt face such issues anyways thanks will note it for future reference
Request failed with status code 419:
I got this error for login and register.
How to solve this?
I think it is because of csrf
I don't know how to do this.
for every post request I face with this error.
Read the above comment the solution is provided there Thanks
You need to check the file config/sanctum.php, and see the index 'domains'... There you need to write the yours.