Now that we have learned how to work with forms, let's implement the same knowledge into the login form.
So, let's add the HTML part of the form.
resources/js/Pages/Auth/Login.jsx:
import GuestLayout from '../../Layouts/GuestLayout.jsx'import { Head, useForm } from '@inertiajs/react' export default function Login() { return ( <GuestLayout> <Head title="Log in" /> <form onSubmit={submit}> <div> <label htmlFor="email" className="block font-medium text-sm text-gray-700">Email</label> <input onChange={(e) => setData('email', e.target.value)} id="email" type="email" className="block mt-1 w-full rounded-md shadow-sm border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50" required autoFocus /> {errors.email && (<p className="mt-2 text-sm text-red-600">{errors.email}</p>)} </div> <div className="mt-4"> <label htmlFor="password" className="block font-medium text-sm text-gray-700">Password</label> <input onChange={(e) => setData('password', e.target.value)} id="password" type="password" className="block mt-1 w-full rounded-md shadow-sm border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50" required /> {errors.password && (<p className="mt-2 text-sm text-red-600">{errors.password}</p>)} </div> <div className="block mt-4"> <label className="flex items-center"> <input checked={data.remember} onChange={(e) => setData('remember', e.target.checked)} type="checkbox" name="remember" className="rounded border-gray-300 text-indigo-600 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50" /> <span className="ml-2 text-sm text-gray-600">Remember me</span> </label> </div> <div className="flex items-center justify-end mt-4"> <button className="inline-flex items-center px-4 py-2 bg-gray-800 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-gray-700 active:bg-gray-900 focus:outline-none focus:border-gray-900 focus:shadow-outline-gray transition ease-in-out duration-150 ml-4"> Log in </button> </div> </form> </GuestLayout> );}
The form itself is very similar to the post form. This is the template part of the React component.
Now, in the script part of the Vue component, we must define the form.
resources/js/Pages/Auth/Login.jsx:
import GuestLayout from '../../Layouts/GuestLayout.jsx'import { Head, useForm } from '@inertiajs/react' export default function Login() { const { data, setData, post, processing, errors, reset } = useForm({ email: '', password: '', remember: false, }); return ( <GuestLayout> <Head title="Log in" /> <form onSubmit={submit}> <div> <label htmlFor="email" className="block font-medium text-sm text-gray-700">Email</label> <input onChange={(e) => setData('email', e.target.value)} id="email" type="email" className="block mt-1 w-full rounded-md shadow-sm border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50" required autoFocus /> {errors.email && (<p className="mt-2 text-sm text-red-600">{errors.email}</p>)} </div> <div className="mt-4"> <label htmlFor="password" className="block font-medium text-sm text-gray-700">Password</label> <input onChange={(e) => setData('password', e.target.value)} id="password" type="password" className="block mt-1 w-full rounded-md shadow-sm border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50" required /> {errors.password && (<p className="mt-2 text-sm text-red-600">{errors.password}</p>)} </div> <div className="block mt-4"> <label className="flex items-center"> <input checked={data.remember} onChange={(e) => setData('remember', e.target.checked)} type="checkbox" name="remember" className="rounded border-gray-300 text-indigo-600 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50" /> <span className="ml-2 text-sm text-gray-600">Remember me</span> </label> </div> <div className="flex items-center justify-end mt-4"> <button className="inline-flex items-center px-4 py-2 bg-gray-800 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-gray-700 active:bg-gray-900 focus:outline-none focus:border-gray-900 focus:shadow-outline-gray transition ease-in-out duration-150 ml-4"> Log in </button> </div> </form> </GuestLayout> );}
Now, we can see the form in the browser.
For the back end, first, let's add the login.post
route.
routes/web.php:
Route::view('/', 'dashboard')->name('dashboard'); Route::resource('posts', PostController::class);Route::inertia('about', 'About')->name('about');Route::inertia('login', 'Auth/Login')->name('login');Route::post('login', [\App\Http\Controllers\Auth\LoginController::class, 'store'])->name('login.post');
Of course, we need LoginController
.
php artisan make:controller Auth/LoginController
In the Controller we will use the LoginRequest
from Laravel Breeze and will use the same logic in the store()
method from Breeze.
app/Http/Controllers/Auth/LoginController.php:
use App\Http\Controllers\Controller;use Illuminate\Http\RedirectResponse;use App\Http\Requests\Auth\LoginRequest; class LoginController extends Controller{ public function store(LoginRequest $request): RedirectResponse { $request->authenticate(); $request->session()->regenerate(); return redirect()->intended(route('posts.index')); }}
Notice: we assume that the user already exists in the DB, you created a user manually before, with a registration form or manually via DB.
After trying to log in, we were redirected to the posts page. Now, we can protect routes using the auth
Middleware.
routes/web.php:
Route::view('/', 'dashboard')->name('dashboard'); Route::middleware('auth')->group(function () { Route::resource('posts', PostController::class); Route::inertia('about', 'About')->name('about');}); Route::inertia('login', 'Auth/Login')->name('login');Route::post('login', [\App\Http\Controllers\Auth\LoginController::class, 'store'])->name('login.post');
If you try entering these pages as a guest, you will be redirected to the login page.
As a homework, you can build the register functionality.
It's almost identical, and you can copy the back-end from Laravel Breeze or some other starter kit. This should be your practice, and I will also avoid repeating myself with another lesson about the same things in forms.
Now, let's work on the logout.