laravel 开发youtube项目1-登录注册

安装Jetstream

bash 复制代码
composer require laravel/jetstream
使用Livewire安装Jetstream
复制代码
php artisan jetstream:install livewire

首页控制器

go 复制代码
php artisan make:controller HomeController --invokable
php 复制代码
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class HomeController extends Controller
{
    /**
     * Handle the incoming request.
     */
    public function __invoke(Request $request)
    {
        return view('home');
    }
}
路由
rust 复制代码
use App\Http\Controllers\HomeController;


// 首页
Route::get('/',HomeController::class)->name('home');
添加迁移文件

Database\Migrations\2014_10_12_000000_create_users_table.php

scss 复制代码
public function up(): void
{
    Schema::create('users', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->string('username')->unique();
        $table->string('email')->unique();
        $table->timestamp('email_verified_at')->nullable();
        $table->string('password');
        $table->rememberToken();
        $table->foreignId('current_team_id')->nullable();
        $table->string('profile_photo_path', 2048)->nullable();
        $table->string('banner_image')->nullable();
        $table->string('channel_description')->nullable();
        $table->timestamps();
    });
}

执行迁移命令

复制代码
php artisan migrate

安装Livewire:在你的项目中,使用Composer安装Livewire库。可以通过运行以下命令来完成安装:

bash 复制代码
composer require livewire/livewire

安装MaryUI

css 复制代码
composer require robsontenorio/mary

npm i -D tailwindcss daisyui@latest postcss autoprefixer && npx tailwindcss init -p

tailwind.config.js 编写

less 复制代码
content: [
    "./vendor/robsontenorio/mary/src/View/Components/**/*.php"
],


plugins: [
    require("daisyui")
],

User模型设置白名单

ini 复制代码
protected $fillable = [
     ...
     ...
    'username',
    'banner_image',
    'channel_description'
];

前端模版

添加登记和注册按钮

resources/views/navigation-menu.blade.php

xml 复制代码
<!-- Navigation Links -->
    <div class="hidden space-x-8 sm:-my-px sm:ms-10 sm:flex">
        <x-nav-link href="{{ route('dashboard') }}" :active="request()->routeIs('dashboard')">
            {{ __('Dashboard') }}
        </x-nav-link>
    </div>
</div>

<!-- 登录注册 -->
@guest
    <div class="hidden sm:flex sm:items-center sm:ms-6">
        <x-nav-link href="{{ route('login') }}" :active="request()->routeIs('dengl')">
            {{ __('登录') }}
        </x-nav-link>
        <x-nav-link href="{{ route('register') }}" :active="request()->routeIs('register')">
            {{ __('注册') }}
        </x-nav-link>
    </div>
@endguest

效果图:

删除MaryUI 组件

input.bide.php、welcome.blagg.php、dropdown.biade.php、dropdown-link.biade.php

删除欢迎界面 <x-welcome / >

resources/views/dashboard.blade.php

xml 复制代码
<x-app-layout>
    <x-slot name="header">
        <h2 class="font-semibold text-xl text-gray-800 leading-tight">
            {{ __('Dashboard') }}
        </h2>
    </x-slot>

    <div class="py-12">
        <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
            <div class="bg-white overflow-hidden shadow-xl sm:rounded-lg">
<x-welcome / > // 删除
            </div>
        </div>
    </div>
</x-app-layout>
启动个人资料图片

config/Jetstream,开启Features::profilePhotos()

ini 复制代码
'features' => [
     Features::profilePhotos(),
],
账户设置添加控制器

App\Actions\Fortify\UpdateUserProfileInformation.php

php 复制代码
public function update(User $user, array $input): void
{
    Validator::make($input, [
        'name' => ['required', 'string', 'max:255'],
        'username' => ['required', 'string', 'max:255', Rule::unique('users')->ignore($user->id)],
        'email' => ['required', 'email', 'max:255', Rule::unique('users')->ignore($user->id)],
        'photo' => ['nullable', 'mimes:jpg,jpeg,png', 'max:1024'],
    ])->validateWithBag('updateProfileInformation');

    if (isset($input['photo'])) {
        $user->updateProfilePhoto($input['photo']);
    }

    if ($input['email'] !== $user->email &&
        $user instanceof MustVerifyEmail) {
        $this->updateVerifiedUser($user, $input);
    } else {
        $user->forceFill([
            'name' => $input['name'],
            'username' => $input['username'],
            'email' => $input['email'],
        ])->save();
    }
}

'username' => ['required', 'string', 'max:255', Rule::unique('users')->ignore($user->id)],, 为自己添加的

账号设置页面

resources/views/profile/update-profile-information-form.blade.php 添加username 字段

xml 复制代码
<!-- Name -->
<div class="col-span-6 sm:col-span-4">
    <x-input label="Name" id="name" type="text" class="mt-1 block w-full" wire:model="state.name" required autocomplete="name" />
    <x-input-error for="name" class="mt-2" />
</div>

<div class="col-span-6 sm:col-span-4">
    <x-input label="Username" id="username" type="text" class="mt-1 block w-full" wire:model="state.username" required autocomplete="username" />
    <x-input-error for="username" class="mt-2" />
</div>

<!-- Email -->
<div class="col-span-6 sm:col-span-4">
    <x-input label="Email" id="email" type="email" class="mt-1 block w-full" wire:model="state.email" required autocomplete="username" />
    <x-input-error for="email" class="mt-2" />
    
<x-button type="sybmit" wire:loading.attr="disabled" wire:target="photo">
    {{ __('Save') }}
</x-button>

type="sybmit" 此为按钮

修改密码页面

resources/views/profile/update-password-form.blade.php

ini 复制代码
<x-slot name="form">
    <div class="col-span-6 sm:col-span-4">
        <x-input lable="Current password" id="current_password" type="password" class="mt-1 block w-full" wire:model="state.current_password" autocomplete="current-password" />
        <x-input-error for="current_password" class="mt-2" />
    </div>

    <div class="col-span-6 sm:col-span-4">
        <x-input lable="Password" id="password" type="password" class="mt-1 block w-full" wire:model="state.password" autocomplete="new-password" />
        <x-input-error for="password" class="mt-2" />
    </div>

    <div class="col-span-6 sm:col-span-4">
        <x-input lable="Confirm password" id="password_confirmation" type="password" class="mt-1 block w-full" wire:model="state.password_confirmation" autocomplete="new-password" />
        <x-input-error for="password_confirmation" class="mt-2" />
    </div>
</x-slot>



<x-button type="sybmit">
    {{ __('Save') }}
</x-button>

resources/views/profile/two-factor-authentication-form.blade.php

less 复制代码
@if ($showingConfirmation)
    <div class="mt-4">
        <x-input label="code" id="code" type="text" name="code" class="block mt-1 w-1/2" inputmode="numeric" autofocus autocomplete="one-time-code"
            wire:model="code"
            wire:keydown.enter="confirmTwoFactorAuthentication" />

        <x-input-error for="code" class="mt-2" />
    </div>
@endif

注册页面

resources/views/auth/login.blade.php

xml 复制代码
<x-guest-layout>
    <x-authentication-card>
        <x-slot name="logo">
            <x-authentication-card-logo />
        </x-slot>

        <x-validation-errors class="mb-4" />

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

            <div>
                <x-input label="昵称" id="name" class="block mt-1 w-full" type="text" name="name" :value="old('name')" required autofocus autocomplete="name" />
            </div>

            <div class="mt-4">
                <x-input label="用户名" id="username" class="block mt-1 w-full" type="text" name="username" :value="old('username')" required autofocus autocomplete="username" />
            </div>

            <div class="mt-4">
                <x-input label="电子邮箱" id="email" class="block mt-1 w-full" type="email" name="email" :value="old('email')" required autocomplete="username" />
            </div>

            <div class="mt-4">
                <x-input label="密码" id="password" class="block mt-1 w-full" type="password" name="password" required autocomplete="new-password" />
            </div>

            <div class="mt-4">
                <x-input label="确认密码" id="password_confirmation" class="block mt-1 w-full" type="password" name="password_confirmation" required autocomplete="new-password" />
            </div>

            @if (Laravel\Jetstream\Jetstream::hasTermsAndPrivacyPolicyFeature())
                <div class="mt-4">
                    <x-label for="terms">
                        <div class="flex items-center">
                            <x-checkbox name="terms" id="terms" required />

                            <div class="ms-2">
                                {!! __('I agree to the :terms_of_service and :privacy_policy', [
                                        'terms_of_service' => '<a target="_blank" href="'.route('terms.show').'" class="underline text-sm text-gray-600 hover:text-gray-900 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">'.__('Terms of Service').'</a>',
                                        'privacy_policy' => '<a target="_blank" href="'.route('policy.show').'" class="underline text-sm text-gray-600 hover:text-gray-900 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">'.__('Privacy Policy').'</a>',
                                ]) !!}
                            </div>
                        </div>
                    </x-label>
                </div>
            @endif

            <div class="flex items-center justify-end mt-4">
                <a class="underline text-sm text-gray-600 hover:text-gray-900 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" href="{{ route('login') }}">
                    {{ __('已经注册?') }}
                </a>

                <x-button class="ms-4" type="submit">
                    {{ __('注册') }}
                </x-button>
            </div>
        </form>
    </x-authentication-card>
</x-guest-layout>
效果图:
config\fortify.php 修改成 identity
ini 复制代码
'username' => 'identity',

'email' => 'identity',
登录控制器验证改造

App\Providers\FortifyServiceProvider

php 复制代码
public function boot(): void
{
  
    Fortify::authenticateUsing(function (LoginRequest $request) {
        $user = User::where('email', $request->identity)
            ->orWhere('username', $request->identity)->first();

        if (
            $user &&
            Hash::check($request->password, $user->password)
        ) {
            return $user;
        }
    });

 
}

登录页面

resources/views/auth/login.blade.php

xml 复制代码
<x-guest-layout>
    <x-authentication-card>
        <x-slot name="logo">
            <x-authentication-card-logo />
        </x-slot>

        <x-validation-errors class="mb-4" />

        @if (session('status'))
            <div class="mb-4 font-medium text-sm text-green-600">
                {{ session('status') }}
            </div>
        @endif

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

            <div>
                <x-input label="电子邮箱/用户名" id="identity" class="block mt-1 w-full" type="text" name="identity" :value="old('identity')" required autofocus autocomplete="identity" />
            </div>

            <div class="mt-4">
                <x-input label="密码" id="password" class="block mt-1 w-full" type="password" name="password" required autocomplete="current-password" />
            </div>

            <div class="block mt-4">
                <label for="remember_me" class="flex items-center">
                    <x-checkbox id="remember_me" name="remember" />
                    <span class="ms-2 text-sm text-gray-600">{{ __('记住我') }}</span>
                </label>
            </div>

            <div class="flex items-center justify-end mt-4">
                @if (Route::has('password.request'))
                    <a class="underline text-sm text-gray-600 hover:text-gray-900 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" href="{{ route('password.request') }}">
                        {{ __('忘记密码?') }}
                    </a>
                @endif

                <x-button type="submit" class="ms-4">
                    {{ __('登录') }}
                </x-button>
            </div>
        </form>
    </x-authentication-card>
</x-guest-layout>

identity为用户名和电子邮箱登录

效果图:
相关推荐
舒一笑9 分钟前
大模型时代的程序员成长悖论:如何在AI辅助下不失去竞争力
后端·程序员·掘金技术征文
lang2015092811 分钟前
Spring Boot优雅关闭全解析
java·spring boot·后端
小羊在睡觉1 小时前
golang定时器
开发语言·后端·golang
用户21411832636021 小时前
手把手教你在魔搭跑通 DeepSeek-OCR!光学压缩 + MoE 解码,97% 精度还省 10-20 倍 token
后端
追逐时光者1 小时前
一个基于 .NET 开源、功能强大的分布式微服务开发框架
后端·.net
刘一说2 小时前
Spring Boot 启动慢?启动过程深度解析与优化策略
java·spring boot·后端
壹佰大多2 小时前
【spring如何扫描一个路径下被注解修饰的类】
java·后端·spring
间彧2 小时前
Java双亲委派模型的具体实现原理是什么?
后端
间彧2 小时前
Java类的加载过程
后端
DokiDoki之父2 小时前
Spring—注解开发
java·后端·spring