主题
用户登录
上节内容,我们已经学习了如何在 Laravel 中实现用户注册功能。了解了基本的控制器
, 模型
,视图
和路由
的使用。接下来我们来学习如何实现用户登录功能。用户登录是网站基本的功能需求,即对用户进行身份验证。用户登录通常需要用户输入用户名和密码,然后系统验证这些信息是否正确。如果验证通过,系统将返回一个会话令牌,用户可以使用这个令牌来访问网站的其他部分。
登录界面
和注册一样,网站首先需要提供一个登录界面。我们还是使用之前的步骤来创建登录界面。三步骤
- 创建控制器
- 创建视图
- 添加路由
创建控制器
shell
php artisan make:controller LoginController
找到该文件,然后添加一个 index
和login
方法
php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
// 这个是用户认证的门面
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
//
public function index()
{
return view('login');
}
public function store(Request $request)
{
}
}
创建视图
shell
php artisan make:view login
找到 resources/views/login.blade.php
文件,然后添加如下代码。我们在用户表是限制 邮箱
是唯一的,所以我们使用邮箱作为登录账号
html
<x-layout>
<x-slot:header>用户登录</x-slot:header>
<div class="flex flex-col justify-center min-h-full px-6 py-12 lg:px-8">
<div class="sm:mx-auto sm:w-full sm:max-w-sm">
<img class="w-auto h-10 mx-auto" src="https://tailwindui.com/plus/img/logos/mark.svg?color=indigo&shade=600" alt="Your Company" />
<h2 class="mt-10 font-bold tracking-tight text-center text-gray-900 text-2xl/9">登 录</h2>
</div>
<div class="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
<form class="space-y-6" action="/login" method="POST">
<label class="input input-bordered flex items-center gap-2 @error('email') input-error @enderror">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-4 h-4 opacity-70">
<path d="M2.5 3A1.5 1.5 0 0 0 1 4.5v.793c.026.009.051.02.076.032L7.674 8.51c.206.1.446.1.652 0l6.598-3.185A.755.755 0 0 1 15 5.293V4.5A1.5 1.5 0 0 0 13.5 3h-11Z" />
<path d="M15 6.954 8.978 9.86a2.25 2.25 0 0 1-1.956 0L1 6.954V11.5A1.5 1.5 0 0 0 2.5 13h11a1.5 1.5 0 0 0 1.5-1.5V6.954Z" />
</svg>
<input type="text" class="grow " placeholder="邮箱" name="email" value="{{ old('email') }}" />
</label>
@error('email')
<div class="text-white alert alert-error">{{ $message }}</div>
@enderror
<label class="input input-bordered flex items-center gap-2 @error('password') input-error @enderror">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-4 h-4 opacity-70">
<path
fill-rule="evenodd"
d="M14 6a4 4 0 0 1-4.899 3.899l-1.955 1.955a.5.5 0 0 1-.353.146H5v1.5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1-.5-.5v-2.293a.5.5 0 0 1 .146-.353l3.955-3.955A4 4 0 1 1 14 6Zm-4-2a.75.75 0 0 0 0 1.5.5.5 0 0 1 .5.5.75.75 0 0 0 1.5 0 2 2 0 0 0-2-2Z"
clip-rule="evenodd" />
</svg>
<input type="password" class="grow" name="password" placeholder="密码" value="{{ old('password') }}" />
</label>
@error('password')
<div class="text-white alert alert-error">{{ $message }}</div>
@enderror
<div>
<button
type="submit"
class="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm/6 font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">
登 录
</button>
</div>
@csrf
</form>
</div>
</div>
</x-layout>
WARNING
记得一定要添加 @csrf
令牌,否则表单提交时会报错。
添加路由
在 routes/web.php 文件中添加路由
php
// 登录页面路由
Route::get('/login', [\App\Http\Controllers\LoginController::class, 'index']);
// 登录处理路由
Route::post('/login', [\App\Http\Controllers\LoginController::class, 'store']);
做完这些, 你就可以在浏览器中访问 /login
路由,看到登录界面了。如图所示
用户登录
我们先不急着点击登录,因为从上一节的注册功能中知道,这时候点击一定是空白的。让我们再回到 LoginController
控制器中的 store
方法,添加登录逻辑,首先还是对字段进行校验
php
public function store(Request $request)
{
// 添加验证逻辑
$request->validate([
'email' => 'required|email',
'password' => 'required|min:6|max:16|alpha_num',
], [
'email.required' => '请输入邮箱',
'email.email' => '请输入正确的邮箱格式',
'password.required' => '请输入密码',
'password.min' => '密码长度不能小于6位',
'password.max' => '密码长度不能大于16位',
'password.alpha_num' => '密码只能由字母和数字组成'
]);
// 这里进行登录逻辑
}
到这里我们先不往下进行,先了解一下 Laravel 认证。Laravel 认证是 Laravel 提供的一个非常方便的认证系统,它使用 User
模型来存储用户信息,并提供了一系列的认证方法。我们可以通过 Auth
门面(先不用管门面这种概念,你只需要知道这是认证类即可)来进行认证。 首先,我们需要在 config/auth.php
文件中配置认证驱动,这里我们使用 database
驱动。来看一下 config/auth.php
文件的配置。这里我只用到认证需要的一些配置,其他无用的配置可以根据需要自己去查看
php
return [
// defaults 配置 Auth 认证的守卫
// 例如目前我们这个系统就是用 `App\Modeles\User` 模型来认证用户
// 默认 guard 守卫是 web (就当做一个名字好了)
'defaults' => [
'guard' => env('AUTH_GUARD', 'web'),
'passwords' => env('AUTH_PASSWORD_BROKER', 'users'),
],
/**
* 守卫数组,每个守卫对应一个认证模型
*/
'guards' => [
'web' => [
'driver' => 'session', // 驱动使用 session 会话,如果是 api 项目,这里可能配置就是 JWT
'provider' => 'users', // 认证服务提供者
],
],
/**
* 认证服务提供者,说白了,这里就是确定你使用哪个数据源的
*
* 驱动可以是 database、eloquent、token、remember、hash
*/
'providers' => [
'users' => [
'driver' => 'eloquent', // 我们这里就是使用 Eloquent 模型来认证用户
'model' => env('AUTH_MODEL', App\Models\User::class),
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
];
说这么多,不如实践一下试试。还是再回到 LoginController
控制器中的 store
方法,添加登录逻辑。
php
// 这里进行登录逻辑
if (Auth::attempt([
'email' => $request->get('email'),
'password' => $request->get('password')
])) {
// 登录成功就跳转到首页
return redirect('/');
}
// 如果登录失败,则返回错误信息
// withInput 保留邮箱的输入信息
return redirect('/login')->withErrors([
'password' => '登录失败'
])->withInput($request->except('password'));
使用 Auth::attempt
方法进行认证,使用 邮箱
和密码
进行认证。如果认证成功,就跳转到首页,如果认证失败,则返回错误信息。
还要做一个小优化,如果用户登录了,则不能再继续访问登录页面。所以我们需要做一下判断,回到 LoginController
控制器中的 index
方法。
php
public function index()
{
// 如果用户已经登录,则跳转到首页
if (Auth::user()) {
return redirect('/');
}
return view('login');
}
如果登录了再访问登录页面,就直接跳转到首页。当然注册页面也是同样的道理,如果用户已经注册了,则不能继续访问注册页面。所以我们需要做一下判断,回到 ReigsterController
控制器中的 index
方法。
php
public function index()
{
if (Auth::user()) {
return redirect('/');
}
return view('register');
}
登录功能就这样完成了。非常简单。这一节内容主要涉及到 Auth
认证。所以需要详细了解相关内容的话,看一下认证文档
下一节内容,在登录的条件下,我们需要在页面上显示已经登录的用户,以及退出功能