Laravel 8 自定义登录:使用用户名而非邮箱进行认证

Laravel 8 自定义登录:使用用户名而非邮箱进行认证

laravel 默认的认证系统使用邮箱作为用户登录凭证。本文将详细指导如何在 laravel 8 应用中,通过重写 logincontroller 中的 username() 方法,将默认的邮箱登录机制修改为使用自定义的用户名(例如 name 字段)进行认证,从而实现灵活的用户登录体验。

理解 Laravel 认证机制

Laravel 框架提供了一套强大且易于使用的认证系统。通过 laravel/ui 或 laravel/breeze 等前端脚手架包,可以快速搭建起用户注册、登录和密码重置功能。在默认实现中,App/Http/Controllers/Auth/LoginController 控制器使用了 Illuminate/Foundation/Auth/AuthenticatesUsers Trait。这个 Trait 封装了处理用户登录请求的核心逻辑。

AuthenticatesUsers Trait 内部默认使用 email 字段作为用户身份验证的凭证字段。这意味着,即使您在登录视图 (login.blade.php) 中将输入框的 name 属性改为 name 或其他字段,Laravel 认证系统在后台仍然会尝试使用 email 字段来查找用户。这就是为什么在修改了视图后,注册功能正常但登录却无法成功的原因。

解决方案:重写 username() 方法

要解决这个问题,我们需要告知 Laravel 认证系统,我们希望使用哪个字段来替代 email 作为登录凭证。AuthenticatesUsers Trait 提供了一个 username() 方法,该方法用于返回登录凭证字段的名称。默认情况下,它返回 email。通过在 LoginController 中重写此方法,我们可以将其指向我们希望使用的字段,例如 name。

实现步骤

以下是修改 Laravel 8 认证系统以使用用户名(name 字段)进行登录的详细步骤。

1. 检查数据库用户表结构

首先,请确保您的 users 表中包含一个 name 字段,并且该字段被设置为唯一(unique),以确保每个用户的用户名都是唯一的,这对于身份验证至关重要。

// database/migrations/xxxx_xx_xx_xxxxxx_create_users_table.php

use Illuminate/Database/Migrations/Migration;
use Illuminate/Database/Schema/Blueprint;
use Illuminate/Support/Facades/Schema;

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name')->nullable()->unique(); // 确保 name 字段唯一且可用于登录
            // ... 其他用户相关字段,例如 'telegram', 'skills' 等
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
}
登录后复制

2. 修改登录视图 login.blade.php

确保您的登录表单中的用户名输入字段的 name 属性设置为 name。这是用户在前端输入用户名的关键。


通义听悟

通义听悟

阿里云通义听悟是聚焦音视频内容的工作学习AI助手,依托大模型,帮助用户记录、整理和分析音视频内容,体验用大模型做音视频笔记、整理会议记录。

通义听悟85


查看详情
通义听悟

<!-- resources/views/auth/login.blade.php -->

<form method="POST" action="{{ route('login') }}">
    @csrf

    <div class="form-group row">
        <label for="name" class="col-md-4 col-form-label text-md-right">{{ __('Username') }}</label>

        <div class="col-md-6">
            <input id="name" type="text" class="form-control @error('name') is-invalid @enderror" name="name" value="{{ old('name') }}" required autocomplete="name" autofocus>

            @error('name')
                <span class="invalid-feedback" role="alert">
                    <strong>{{ $message }}</strong>
                </span>
            @enderror
        </div>
    </div>

    <div class="form-group row">
        <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
        <div class="col-md-6">
            <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">
            @error('password')
                <span class="invalid-feedback" role="alert">
                    <strong>{{ $message }}</strong>
                </span>
            @enderror
        </div>
    </div>

    <!-- ... 其他表单元素和按钮,如“记住我”和“忘记密码”链接 ... -->
</form>
登录后复制

3. 更新 LoginController

这是最关键的一步。在 App/Http/Controllers/Auth/LoginController.php 中,添加一个 username() 方法来指定登录凭证字段。

// app/Http/Controllers/Auth/LoginController.php

namespace App/Http/Controllers/Auth;

use App/Http/Controllers/Controller;
use App/Providers/RouteServiceProvider;
use Illuminate/Foundation/Auth/AuthenticatesUsers;

class LoginController extends Controller
{
    use AuthenticatesUsers;

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
    protected $redirectTo = RouteServiceProvider::HOME;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }

    /**
     * Get the login username to be used by the controller.
     *
     * @return string
     */
    public function username()
    {
        return 'name'; // 将默认的 'email' 改为 'name'
    }
}
登录后复制

通过添加 public function username() { return ‘name’; },您就覆盖了 AuthenticatesUsers Trait 中的默认行为,指示 Laravel 认证系统使用 name 字段进行用户查找和验证。

4. 确保用户模型 User.php 配置正确

虽然与登录机制的核心修改关系不大,但为了完整性,请确保您的 User 模型 (App/Models/User.php) 的 $fillable 数组中包含 name 字段,以便在用户注册时能够正确保存用户名。

// app/Models/User.php

namespace App/Models;

use Illuminate/Contracts/Auth/MustVerifyEmail;
use Illuminate/Database/Eloquent/Factories/HasFactory;
use Illuminate/Foundation/Auth/User as Authenticatable;
use Illuminate/Notifications/Notifiable;
use Laravel/Sanctum/HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;
    // use /HighIdeas/UsersOnline/Traits/UsersOnlineTrait; // 如果不需要,可以移除

    /**
     * The attributes that are mass assignable.
     *
     * @var string[]
     */
    protected $fillable = [
        'name',
        'password',
        // 'email', // 如果不再使用邮箱作为注册字段,可以根据实际情况移除或保留
        'skills',
        'education',
        'sponsor',
        'telegram',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    // ... 其他方法和属性,如 relationships
}
登录后复制

注意事项

  • 唯一性约束: 确保您选择作为登录凭证的字段(如 name)在数据库中具有唯一性约束。否则,可能会导致认证混乱或安全问题。
  • 验证规则: 在 RegisterController 或任何处理用户注册的控制器中,确保为 name 字段设置了适当的验证规则,例如 required|string|max:255|unique:users。
  • 注册与登录一致性: 注册时用户提供的字段应与登录时使用的字段保持一致。
  • 密码重置: 如果您启用了密码重置功能,请注意密码重置通常仍依赖于邮箱。如果您也希望修改密码重置机制,那将需要更深入地修改 Forgot Password 和 Reset Password 控制器,这通常涉及重写 SendsPasswordResetEmails 和 ResetsPasswords Trait 中的相关方法。
  • 多字段登录: 如果您希望用户可以使用 name 或 email 中的任意一个进行登录,则需要实现更复杂的自定义逻辑,通常涉及在 LoginController 中重写 credentials() 方法来动态判断用户输入的凭证类型。

总结

通过在 LoginController 中简单地重写 username() 方法,您可以轻松地将 Laravel 8 的默认登录凭证从邮箱更改为自定义的用户名字段。这一改动非常直接且高效,能够满足许多应用场景下使用用户名进行认证的需求,同时保持 Laravel 认证系统的其余功能不变。在实施此类修改时,请务必注意数据模型的一致性和字段的唯一性,以确保系统的稳定性和安全性。

以上就是Laravel 8 自定义登录:使用用户名而非邮箱进行认证的详细内容,更多请关注php中文网其它相关文章!

https://www.php.cn/faq/1674595.html

发表回复

Your email address will not be published. Required fields are marked *