Monday, September 19, 2022

Authentication for Vue 3, Laravel 9 with Sanctum

 1) Kernel.php -> uncomment
'api' => [
             \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
            'throttle:api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,

 2) php artisan make:controller API/AuthController

 

<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use App\Models\User;
use Illuminate\Support\Facades\Auth;


class AuthController extends Controller
{
    public function register(Request $request){
        $validator = Validator::make($request->all(), [
            'name' => 'required',
            'email' => 'required|email|unique:users',
            'password'=> 'required',
            'c_password'=>'required|same:password'
        ],[
            'email.required' => 'The User Email must be a valid email address.'
         ]);
        if($validator->fails()){
            $response = [
                'success' =>false,
                'message'=>$validator->errors()
            ];
            return response()->json($response,400);
        }
        $input = $request->all();
        $input['password'] = bcrypt($input['password']);
        $user = User::create($input);
       
        $success['token']= $user->createToken('MyApp')->plainTextToken;
        $success['name'] = $user->name;

        $response = [
            'success' =>true,
            'data'=>$success,
            'message' =>'User register successfully',
           
        ];
        return response()->json($response,200);


    }
    public function login(Request $request){
        if(Auth::attempt(['email'=>$request->email,'password'=>$request->password])){
            $user = Auth::user();
            $success['token']= $user->createToken('MyApp')->plainTextToken;
            $success['name'] = $user->name;

        $response = [
            'success' =>true,
            'data'=>$success,
            'message' =>'User login successfully',
           
        ];
            return response()->json($response,200);
        }else{
            $response = [
                'success' =>false,
                'message' =>'Unauthorised Access'
            ];
            return response()->json($response);
        }
    }
}

3) register.vue

<template>
    <h1>Register here</h1>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-sm-6 mt-4">
                <p class="text-danger" v-for="error in errors" :key="error">
                    <span v-for="err in error" :key="err">{{ err }}</span>
                    </p>
                <form @submit.prevent="register" >
                    <div class="form-group">
                        <label for="name">Full Name</label>
                        <input type="text" class="form-control" v-model="form.name" >
                        <label for="username">Login Email</label>
                        <input type="text" class="form-control" v-model="form.email" >
                        <label for="password">Password</label>
                        <input type="password" class="form-control" v-model="form.password">
                        <label for="password">Confirm Password</label>
                        <input type="password" class="form-control" v-model="form.c_password">
                        <button type="submit" class="btn btn-primary mt-3">Submit</button>
                    </div>
                </form>

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

<script>
    import axios from 'axios';
import { reactive, ref } from 'vue'
import { useRouter } from "vue-router"
export default {
    setup () {
        const router = useRouter();
        let form = reactive({
            name: '',
            email: '',
            password: '',
            c_password: ''
        });
        let errors = ref([])
        const register = async()=>{
            await axios.post('/api/register',form).then(res=>{
                if(res.data.success){
                    localStorage.setItem('token',res.data.data.token)
                    router.push({name:'dashboard'})
                }
            }).catch(e=>{
                errors.value = e.response.data.message
            })
        }
        return{
            form,
            register,
            errors
        }
    }
}
</script>

4) App.js or Routes.js

require('./bootstrap');

import {createApp} from 'vue'
import * as VueRouter from 'vue-router'

import login from './components/login.vue'
import TaskComponent from './components/TaskComponent.vue'
import CCTVComponent from './components/CCTVComponent.vue'
import SubComponent from './components/SubscriptionComponent.vue'
import dashboard from './components/dashboard.vue'
import register from './components/register.vue'

const routes = [
    {path: '/', name:'login', component: login, meta:{requiresAuth:false }},
    {path: '/tasks', component: TaskComponent, meta:{requiresAuth:true }},
    {path: '/cameras', component: CCTVComponent, meta:{requiresAuth:true }},
    {path: '/subs', component: SubComponent, meta:{requiresAuth:true }},
    {path: '/dashboard', name: 'dashboard', component: dashboard, meta:{requiresAuth:true }},
    {path: '/register', name: 'register', component: register, meta:{requiresAuth:false }}
]

const router = VueRouter.createRouter({
    history: VueRouter.createWebHistory(),
    routes,
    linkActiveClass: "active",
    linkExactActiveClass: "exact-active",
})
window.url = ''
const app = createApp({})


router.beforeEach((to,from)=>{
    if(to.meta.requiresAuth && !localStorage.getItem('token') ){
        return { name:'login' }
    }
    if(to.meta.requiresAuth == false && localStorage.getItem('token') ){
        return { name:'dashboard' }
    }
})


app.use(router)

app.mount('#app')


5) Dashboard or Logout 

<template lang="">
    <div class="container">
        <h2>Dashboard :</h2>
        <button type="button" class="btn btn-dark mt-2" @click="logout">Logout</button>
    </div>
</template>
<script>
    import { useRouter } from "vue-router"
export default {
    setup(){
        const router = useRouter();
        function logout(){
            localStorage.removeItem('token');
            router.push({name:'login'})
        }
        return {
            logout
        }
    }
}
</script>
<style lang="">
   
</style>

In API.php add those route

Route::controller(AuthController::class)->group(function () {
    Route::post('login', 'login');
    Route::post('register', 'register');
    Route::post('logout', 'logout');
    Route::post('refresh', 'refresh');
    Route::get('me', 'me');

});


 

6) login.vue

<template>
    <h1>Login here</h1>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-sm-6 mt-4">
                <p class="text-danger" v-if="error" >{{ error }}</p>
                <form @submit.prevent="login" >
                    <div class="form-group">
                       
                        <label for="username">Login Email</label>
                        <input type="email" class="form-control" v-model="form.email" >
                        <label for="password">Password</label>
                        <input type="password" class="form-control" v-model="form.password">
                        <button type="submit" class="btn btn-primary mt-3">Submit</button>
                    </div>
                </form>

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

<script>
    import axios from 'axios';
import { reactive, ref } from 'vue'
import { useRouter } from "vue-router"
export default {
    setup () {
        const router = useRouter();
        let form = reactive({
            email: '',
            password: ''
        });
        let error = ref('')
        const login = async()=>{
            await axios.post('/api/login',form).then(res=>{
                if(res.data.success){
                    localStorage.setItem('token',res.data.data.token)
                    router.push({name:'dashboard'})
                }else{
                    error.value = res.data.message;
                }
            })
        }
        return{
            form,
            login,
            error
        }
    }
}
</script>

No comments:

Post a Comment