Laravel框架Auth模块编辑指南:注册登录字段增删与表单定制
Hey there! I'll walk you through exactly how to tweak Laravel's Auth system to build that custom registration form with username, phone, and address—plus how to add/remove fields from both registration and login flows. Let's dive in.
1. First: Update the User Database Table
Before we touch any Auth logic, we need to make sure our database can store the new fields. There are two scenarios here:
If you haven't run migrations yet
Open your initial users table migration (usually database/migrations/XXXX_XX_XX_XXXXXX_create_users_table.php) and add the new fields:
public function up() { Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('username')->unique(); // New: Unique username $table->string('phone')->unique(); // New: Unique phone number $table->text('address'); // New: User address $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); $table->rememberToken(); $table->timestamps(); // Remove the 'name' field if you don't need it anymore }); }
Then run php artisan migrate to create the table.
If migrations are already run
Create a new migration to add the fields:
php artisan make:migration add_custom_fields_to_users_table
Edit the new migration file:
public function up() { Schema::table('users', function (Blueprint $table) { $table->string('username')->unique()->after('id'); $table->string('phone')->unique()->after('username'); $table->text('address')->after('phone'); // Optional: Drop the 'name' field if you're replacing it // $table->dropColumn('name'); }); } public function down() { Schema::table('users', function (Blueprint $table) { $table->dropColumn(['username', 'phone', 'address']); // Optional: Restore 'name' if you dropped it // $table->string('name'); }); }
Run the migration with php artisan migrate.
2. Update the User Model
We need to let Laravel know which fields are allowed for mass assignment. Open app/Models/User.php and update the $fillable array:
protected $fillable = [ 'username', 'phone', 'address', 'email', 'password', // Keep 'name' here if you didn't remove it ];
3. Customize the Registration Controller
Next, we'll modify the registration logic to handle the new fields. Depending on which Auth scaffolding you're using:
- Laravel Breeze: Controller is at
app/Http/Controllers/Auth/RegisteredUserController.php - Laravel UI: Controller is at
app/Http/Controllers/Auth/RegisterController.php
Update the validation and user creation code:
public function store(Request $request) { // Validate all new fields $request->validate([ 'username' => ['required', 'string', 'max:255', 'unique:users'], 'phone' => ['required', 'string', 'max:20', 'unique:users', 'regex:/^\+?[0-9]{10,15}$/'], 'address' => ['required', 'string'], 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'], 'password' => ['required', 'confirmed', \Illuminate\Validation\Rules\Password::defaults()], ]); // Create the user with our new fields $user = \App\Models\User::create([ 'username' => $request->username, 'phone' => $request->phone, 'address' => $request->address, 'email' => $request->email, 'password' => \Illuminate\Support\Facades\Hash::make($request->password), ]); // Fire the registered event (keep this for default Auth behavior) event(new \Illuminate\Auth\Events\Registered($user)); // Log the user in immediately \Illuminate\Support\Facades\Auth::login($user); return redirect(\App\Providers\RouteServiceProvider::HOME); }
4. Build the Custom Registration Form
Now let's update the registration view to include our new fields. Find the view file:
- Breeze:
resources/views/auth/register.blade.php - Laravel UI:
resources/views/auth/register.blade.php
Add the new form fields (and remove the 'name' field if you don't need it):
<!-- Username Field --> <div class="mt-4"> <x-input-label for="username" :value="__('Username')" /> <x-text-input id="username" class="block mt-1 w-full" type="text" name="username" :value="old('username')" required autofocus autocomplete="username" /> <x-input-error :messages="$errors->get('username')" class="mt-2" /> </div> <!-- Phone Number Field --> <div class="mt-4"> <x-input-label for="phone" :value="__('Phone Number')" /> <x-text-input id="phone" class="block mt-1 w-full" type="text" name="phone" :value="old('phone')" required autocomplete="phone" /> <x-input-error :messages="$errors->get('phone')" class="mt-2" /> </div> <!-- Address Field --> <div class="mt-4"> <x-input-label for="address" :value="__('Address')" /> <textarea id="address" class="block mt-1 w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500" name="address" required autocomplete="address">{{ old('address') }}</textarea> <x-input-error :messages="$errors->get('address')" class="mt-2" /> </div>
5. Optional: Customize Login to Use Username/Phone
If you want users to log in with username, phone, or email instead of just email, update the login controller:
- Breeze:
app/Http/Controllers/Auth/AuthenticatedSessionController.php - Laravel UI:
app/Http/Controllers/Auth/LoginController.php
Modify the authenticate method (or credentials method for UI):
public function authenticate(Request $request) { $request->validate([ 'login' => ['required', 'string'], 'password' => ['required', 'string'], ]); // Determine if the input is email, username, or phone $fieldType = filter_var($request->login, FILTER_VALIDATE_EMAIL) ? 'email' : (ctype_digit($request->login) ? 'phone' : 'username'); $credentials = [ $fieldType => $request->login, 'password' => $request->password, ]; if (\Illuminate\Support\Facades\Auth::attempt($credentials, $request->filled('remember'))) { $request->session()->regenerate(); return redirect()->intended(\App\Providers\RouteServiceProvider::HOME); } return back()->withErrors([ 'login' => __('The provided credentials do not match our records.'), ])->onlyInput('login'); }
Then update the login view to replace the email field with a "Login" field:
<div class="mt-4"> <x-input-label for="login" :value="__('Email/Username/Phone')" /> <x-text-input id="login" class="block mt-1 w-full" type="text" name="login" :value="old('login')" required autofocus /> <x-input-error :messages="$errors->get('login')" class="mt-2" /> </div>
Quick Notes
- Always test validation rules thoroughly (e.g., phone number regex might need adjustment for your region)
- If you're removing fields like 'name', make sure no other parts of your app depend on it
- For password confirmation, keep the default
password_confirmationfield in the form—it works automatically with theconfirmedrule
内容的提问来源于stack exchange,提问作者styles9

