【原创】Laravel中的会话管理

消息提示

session()->flash('success', '欢迎,您将在这里开启一段新的旅程~');

session() 方法可以用来访问会话实例。当我们想存入一条缓存的数据,让它只在下一次的请求内有效时,则可以使用 flash 方法。flash 方法接收两个参数,第一个为会话的键,第二个为会话的值,我们可以通过下面这行代码的为会话赋值。之后我们可以使用 session()->get('success') 通过键名来取出对应会话中的数据。

接下来的消息提示依然用会话进行闪存,并分别用 danger, warning, success, info 这四个键名在 Bootstrap 分别具有不同样式展现效果。

resources/views/shared/_messages.blade.php

@foreach (['danger', 'warning', 'success', 'info'] as $msg)
  @if(session()->has($msg))
    <div class="flash-message">
      <p class="alert alert-{{ $msg }}">
        {{ session()->get($msg) }}
      </p>
    </div>
  @endif
@endforeach

resources/views/layouts/default.blade.php

<!DOCTYPE html>
<html>
  <head>
    <title>@yield('title', 'Weibo App') - Laravel 入门教程</title>
    <link rel="stylesheet" href="{{ mix('css/app.css') }}">
  </head>

  <body>
    @include('layouts._header')

    <div class="container">
      <div class="offset-md-1 col-md-10">
        @include('shared._messages')
        @yield('content')
        @include('layouts._footer')
      </div>
    </div>
  </body>
</html>

用户登录

if (Auth::attempt(['email' => $email, 'password' => $password])) {
    // 该用户存在于数据库,且邮箱和密码相符合
}

Laravel 中提供的 Authattempt 方法可以完成用户身份认证操作, attempt 方法第一个参数为数组,用于寻找数据库中的用户数据。
attempt 方法执行的代码逻辑如下:

  1. 使用 email 字段的值在数据库中查找;
  2. 如果用户被找到:
    • 先将传参的 password 值进行哈希加密,然后与数据库中 password 字段中已加密的密码进行匹配;
    • 如果匹配后两个值完全一致,会创建一个『会话』给通过认证的用户。在创建会话的同时,也会产生一个名为 laravel_session 的 HTTP Cookie,以此 Cookie 来记录用户登录状态,最终返回 true
    • 如果匹配后两个值不一致,则返回 false
  3. 如果用户未找到,则返回 false

Auth 默认对应的是 App\Models\User::class,它的配置文件位于 config/auth.php.

登录认证代码:

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Auth;

class SessionsController extends Controller
{
    public function store(Request $request)
    {
       $credentials = $this->validate($request, [
           'email' => 'required|email|max:255',
           'password' => 'required'
       ]);

       if (Auth::attempt($credentials)) {
           session()->flash('success', '欢迎回来!');
           return redirect()->route('users.show', [Auth::user()]);
       } else {
           session()->flash('danger', '很抱歉,您的邮箱和密码不匹配');
           return redirect()->back()->withInput();
       }
    }
}

Auth::user() 方法用来获取当前登录用户的信息,并将数据传送给路由。

判断当前用户是否登录

<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
  <div class="container ">
    <a class="navbar-brand" href="{{ route('home') }}">Weibo App</a>
    <ul class="navbar-nav justify-content-end">
      @if (Auth::check())
        <li class="nav-item"><a class="nav-link" href="#">用户列表</a></li>
        <li class="nav-item dropdown">
          <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            {{ Auth::user()->name }}
          </a>
          <div class="dropdown-menu" aria-labelledby="navbarDropdown">
            <a class="dropdown-item" href="{{ route('users.show', Auth::user()) }}">个人中心</a>
            <a class="dropdown-item" href="#">编辑资料</a>
            <div class="dropdown-divider"></div>
            <a class="dropdown-item" id="logout" href="#">
              <form action="{{ route('logout') }}" method="POST">
                {{ csrf_field() }}
                {{ method_field('DELETE') }}
                <button class="btn btn-block btn-danger" type="submit" name="button">退出</button>
              </form>
            </a>
          </div>
        </li>
      @else
        <li class="nav-item"><a class="nav-link" href="{{ route('help') }}">帮助</a></li>
        <li class="nav-item" ><a class="nav-link" href="{{ route('login') }}">登录</a></li>
      @endif
    </ul>
  </div>
</nav>

Auth::check() 用于判断当前用户是否登录,已登录返回 true , 未登录返回 false

伪造 DELETE 请求

<form action="{{ route('logout') }}" method="POST">
  {{ csrf_field() }}
  {{ method_field('DELETE') }}
  <button class="btn btn-block btn-danger" type="submit" name="button">退出</button>
</form>

浏览器不支持发送 DELETE 请求,因此需要使用一个隐藏域来伪造 DELETE 请求。
在 Blade 模板中,可以使用 method_field 方法来创建隐藏域。

{{ method_field('DELETE') }}

这段代码转换为 HTML 代码如下:

<input type="hidden" name="_method" value="DELETE">

自动登录

Auth::login($user);

退出登录

使用 Laravel 默认的 Auth::logout() 方法。

记住我

在 Laravel 的默认配置中,如果用户登录时没有选择 「记住我」 功能,那么用户的登录状态是 两小时。如果使用了该功能,则登录状态会被延长至五年。
Laravel 默认为用户生成的迁移文件中已包含 remember_token 字段,该字段将用于保存『记住我』令牌。
Auth::attempt() 方法可以接受两个参数,第一个是要进行用户身份认证的数组,第二个就是是否开启 「记住我」 功能的布尔值。

if (Auth::attempt($credentials, $request->has('remember'))) {
    //
}

这样就开启了 「记住我」 这个功能。

点赞

发表回复

电子邮件地址不会被公开。必填项已用 * 标注