教你修改 Laravel "记住我" Cookie 的过期时间.

本文适用的 Laravel 版本: 5.2 +

问题

有时候, 网站会提供一个选项, 让用户在7天内免登陆, 或者30天内免登陆, 但是 Laravel 的自带 Auth 模块没有提供选项让我们修改这个过期时间, 那么我们该如何实现这个需求呢?

查看源码

如果要使用 laravel 自带的 Auth 模块是非常简单的, 只要通过 make auth 即可安装.

但是, 在 laravel 的默认设置中, 如果用户勾选了 Remember Me, 那么 Laravel 就会永久保存这个用户的登录状态, 直到用户手动 Logout.

Laravel 文档中是这样描述的
file

在源码中, 也将相关的Cookie 过期时间设置为了 forever.
路径为: vendor/laravel/framework/src/Illuminate/Auth/SessionGuard.php
file

那么, 如何在不修改源码的情况下更改这一设置呢?

解决方法

在运行过 make auth 之后, 在 Controllers 文件夹中, 系统会帮我创建一个 Auth 文件夹, 这个文件夹里放置了一些登录用的 Controller, 我们只要对其中的 LoginController 做一些修改, 就可以实现我们的需求了.


基本思路是这样的, 在 Laravel 将 remember_token 的过期时间设置为 forever 之后, 这个时候还没有将 Cookie 发回到浏览器, 所以我们只要在发回浏览器之前, 再次修改这个 Cookie 的有效期即可.


在打开 LoginController 之后, 我们可以看到

    use AuthenticatesUsers;



也就是说 LoginController 使用了 AuthenticatesUsers trait 中的方法, 我们进入 AuthenticatesUsers 这个 trait. 很容易找到 sendLoginResponse 这个方法, 这个方法的作用是在成功验证用户信息后, 返回登录成功的消息给浏览器. 所以我们只要重写这个方法, 并且在这个方法里加入对 Cookie 有效期的修改操作即可实现我们的需求.


接下来, 我们就在 LoginController 中重写一次这个方法.


首先我们直接将 protected function sendLoginResponse(Request $request) 这个方法从 AuthenticatesUsers 复制到 LoginController 中, 然后再加入修改 Cookie 的代码即可. 修改后的 LoginController 会像下面这样

class LoginController extends Controller
{
    ...

    protected function sendLoginResponse(Request $request)
    {
        // 设置记住我的时间为60分钟
        $rememberTokenExpireMinutes = 60;

        // 首先获取 记住我 这个 Cookie 的名字, 这个名字一般是随机生成的,
        // 类似 remember_web_59ba36addc2b2f9401580f014c7f58ea4e30989d
        $rememberTokenName = Auth::getRecallerName();

        // 再次设置一次这个 Cookie 的过期时间
        Cookie::queue($rememberTokenName, Cookie::get($rememberTokenName), $rememberTokenExpireMinutes);

        // 下面的代码是从 AuthenticatesUsers 中的 sendLoginResponse() 直接复制而来
        $request->session()->regenerate();

        $this->clearLoginAttempts($request);

        return $this->authenticated($request, $this->guard()->user())
            ?: redirect()->intended($this->redirectPath());
    }
}

结束

好了, 现在你就可以在没有修改源代码的情况下, 自定义 "记住我" Cookie 的过期时间了.

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 5年前 自动加精
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 8

不是有登录前 登录中 登录后事件吗?在事件中写也可以啊。不是更简单

6年前 评论

貌似laravel 登录记住我 代码不是自带就有吗?为什么要自己撸?

6年前 评论

先mark,:+1:

6年前 评论

使用Cookie::get($rememberTokenName)获取cookie值有一个问题,这样取出来是一个空值,根据这个帖子
https://stackoverflow.com/questions/446695...
修改为:
$cookieJar = $this->guard()->getCookieJar();
$cookieValue = $cookieJar->queued($rememberTokenName)->getValue();

// 再次设置一次这个 Cookie 的过期时间
Cookie::queue($rememberTokenName, $cookieValue, $rememberTokenExpireMinutes);

5年前 评论
lxiaoqing112 3年前

mark住一波

4年前 评论

为什么我每个账号登进去,没有选中“记住我”都会生成cookie

4年前 评论

头部记得引入use Illuminate\Http\Request; 否则会报错Argument 1 passed to App\Http\Controllers\Auth\LoginController::sendLoginResponse() must be an instance of App\Http\Controllers\Auth\Request, instance of Illuminate\Http\Request given, called in /home/vagrant/code/larabbs/vendor/laravel/framework/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php on line 47

4年前 评论

@SZL_ 会话状态啊,是需要用session cookie来维持的,那么如果使用 记住我, 则会多生成 remember_web的信息

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!