首页 > PHP > Laravel教程 会话和登录

Laravel教程 会话和登录

2025-02-20 12:53:15

一、会话的基础知识

1. 什么是会话(Session)


在 Web 开发中,会话是一种机制,用于在多个页面请求之间跟踪和存储用户的相关信息。HTTP 协议是无状态的,这意味着每次客户端向服务器发送请求时,服务器并不知道这是同一个用户的连续请求。会话机制通过为每个用户分配一个唯一的标识符(通常称为会话 ID),使得服务器能够识别和关联不同请求之间的用户信息。

例如,当用户登录到一个网站后,服务器需要记住该用户已经登录的状态,以便在用户访问其他页面时可以提供相应的权限和个性化内容。会话机制就可以帮助服务器实现这种状态的跟踪。

2. 会话的工作原理


会话的工作流程通常包含以下几个步骤:

  • 会话创建:当用户首次访问网站时,服务器会为该用户创建一个新的会话,并生成一个唯一的会话 ID。这个会话 ID 通常会以 Cookie 的形式发送到客户端浏览器,存储在客户端的本地。
  • 会话跟踪:在后续的请求中,客户端浏览器会自动将存储的会话 ID 包含在请求头中发送给服务器。服务器接收到请求后,根据会话 ID 查找对应的会话数据。
  • 会话数据存储:服务器会将会话数据存储在服务器端的某个存储介质中,如文件系统、数据库或内存。这些数据可以包括用户的登录状态、购物车信息、用户偏好等。
  • 会话结束:会话可以在以下几种情况下结束:
    • 用户主动注销:当用户点击 “注销” 按钮时,服务器会销毁该用户的会话数据。
    • 会话过期:服务器可以设置会话的过期时间,当会话在一段时间内没有活动时,服务器会自动销毁会话数据。
    • 浏览器关闭:虽然有些浏览器会在关闭时清除会话 Cookie,但并不是所有浏览器都这样做。因此,会话的结束通常还是由服务器端的过期机制来控制。

3. 会话与 Cookie 的关系


会话和 Cookie 密切相关,但它们并不是同一个概念。

  • Cookie:是客户端浏览器存储数据的一种机制。服务器可以通过响应头将 Cookie 发送给客户端,客户端浏览器会将这些 Cookie 存储在本地。在后续的请求中,客户端会将这些 Cookie 包含在请求头中发送给服务器。Cookie 可以存储一些简单的信息,如用户的偏好设置、登录状态等。
  • 会话:是服务器端的一种机制,用于跟踪和存储用户的状态信息。会话 ID 通常以 Cookie 的形式存储在客户端,以便服务器能够识别不同的用户。会话数据则存储在服务器端,客户端无法直接访问。

4. 会话的优缺点


  • 优点
    • 安全性高:会话数据存储在服务器端,客户端只能通过会话 ID 来访问,相比直接将敏感信息存储在客户端的 Cookie 中,安全性更高。
    • 数据一致性:服务器可以对会话数据进行集中管理,确保数据的一致性和完整性。
    • 支持复杂数据类型:会话可以存储复杂的数据类型,如数组、对象等,方便存储用户的各种信息。
  • 缺点
    • 服务器压力:会话数据存储在服务器端,会占用服务器的一定资源。当并发用户数较多时,可能会对服务器的性能产生影响。
    • 会话丢失:如果服务器出现故障或重启,可能会导致部分会话数据丢失。

5. Laravel 中的会话配置


在 Laravel 中,会话的配置文件位于 config/session.php。以下是一些常用的配置选项:

  • driver:指定会话的驱动程序,如 filecookiedatabaseredis 等。不同的驱动程序有不同的优缺点,你可以根据项目的需求选择合适的驱动。
'driver' => env('SESSION_DRIVER', 'file'),

  • lifetime:指定会话的过期时间,单位为分钟。
'lifetime' => env('SESSION_LIFETIME', 120),

  • expire_on_close:指定当浏览器关闭时是否销毁会话。
'expire_on_close' => false,

  • cookie:指定会话 Cookie 的名称。
'cookie' => env(
    'SESSION_COOKIE',
    str_slug(env('APP_NAME', 'laravel'), '_').'_session'
),

通过修改这些配置选项,你可以灵活地调整 Laravel 会话的行为。

二、Laravel 登录和会话实现步骤

1. 环境准备


确保你已经安装了 Laravel 项目。如果还未安装,可以使用 Composer 来创建一个新的 Laravel 项目:
composer create-project --prefer-dist laravel/laravel laravel-login-example
cd laravel-login-example

2. 数据库迁移


Laravel 自带了用户认证所需的迁移文件,这些文件位于 database/migrations 目录下。运行以下命令来创建用户表:
php artisan migrate

3. 生成认证脚手架


Laravel 提供了简单的命令来生成认证所需的视图、路由和控制器:
composer require laravel/breeze --dev
php artisan breeze:install

运行以上命令后,Laravel 会自动生成登录、注册等相关的视图文件和路由。

4. 路由


生成认证脚手架后,Laravel 会自动在 routes/web.php 中添加认证相关的路由:
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Auth\AuthenticatedSessionController;

// 登录页面
Route::get('/login', [AuthenticatedSessionController::class, 'create'])
    ->name('login')
    ->middleware('guest');

// 处理登录请求
Route::post('/login', [AuthenticatedSessionController::class, 'store'])
    ->middleware('guest');

// 处理注销请求
Route::post('/logout', [AuthenticatedSessionController::class, 'destroy'])
    ->name('logout')
    ->middleware('auth');

5. 登录控制器


App\Http\Controllers\Auth\AuthenticatedSessionController 控制器负责处理用户登录和注销逻辑:
<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class AuthenticatedSessionController extends Controller
{
    /**
     * 显示登录表单
     */
    public function create()
    {
        return view('auth.login');
    }

    /**
     * 处理登录请求
     */
    public function store(Request $request)
    {
        $credentials = $request->validate([
            'email' => ['required', 'email'],
            'password' => ['required'],
        ]);

        if (Auth::attempt($credentials)) {
            $request->session()->regenerate();
            return redirect()->intended(RouteServiceProvider::HOME);
        }

        return back()->withErrors([
            'email' => 'The provided credentials do not match our records.',
        ])->onlyInput('email');
    }

    /**
     * 处理注销请求
     */
    public function destroy(Request $request)
    {
        Auth::guard('web')->logout();

        $request->session()->invalidate();

        $request->session()->regenerateToken();

        return redirect('/');
    }
}

6. 登录视图


登录视图文件位于 resources/views/auth/login.blade.php,该文件包含了登录表单:
@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Login') }}</div>

                <div class="card-body">
                    <form method="POST" action="{{ route('login') }}">
                        @csrf

                        <div class="row mb-3">
                            <label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Email Address') }}</label>

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

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

                        <div class="row mb-3">
                            <label for="password" class="col-md-4 col-form-label text-md-end">{{ __('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>

                        <div class="row mb-3">
                            <div class="col-md-6 offset-md-4">
                                <div class="form-check">
                                    <input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>

                                    <label class="form-check-label" for="remember">
                                        {{ __('Remember Me') }}
                                    </label>
                                </div>
                            </div>
                        </div>

                        <div class="row mb-0">
                            <div class="col-md-8 offset-md-4">
                                <button type="submit" class="btn btn-primary">
                                    {{ __('Login') }}
                                </button>

                                @if (Route::has('password.request'))
                                    <a class="btn btn-link" href="{{ route('password.request') }}">
                                        {{ __('Forgot Your Password?') }}
                                    </a>
                                @endif
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

7. 会话管理


在 Laravel 中,可以使用 Session 门面来管理会话数据。以下是一些常用的会话操作示例:

存储会话数据

use Illuminate\Support\Facades\Session;

// 存储单个会话数据
Session::put('key', 'value');

// 存储多个会话数据
Session::put([
    'key1' => 'value1',
    'key2' => 'value2'
]);

获取会话数据


收起
php
 
 
 
 
// 获取单个会话数据
$value = Session::get('key');

// 获取会话数据,如果不存在则返回默认值
$value = Session::get('key', 'default');

// 获取所有会话数据
$allData = Session::all();

删除会话数据

// 删除单个会话数据
Session::forget('key');

// 删除所有会话数据
Session::flush();

8. 保护路由


可以使用 auth 中间件来保护需要用户登录才能访问的路由:
Route::get('/dashboard', function () {
    return view('dashboard');
})->middleware(['auth'])->name('dashboard');

以上就是在 Laravel 中实现用户登录和会话管理的基本步骤。通过这些步骤,你可以快速搭建一个简单的用户认证系统。
 
 
使用 Ctrl+D 可将网站添加到书签
收藏网站
扫描二维码
关注早实习微信公众号
官方公众号
Top