教你修改 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 协议》,转载必须注明作者和本文链接
本帖由系统于 6年前 自动加精
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 8

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

8年前 评论

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

8年前 评论

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

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

6年前 评论
lxiaoqing112 4年前

mark 住一波

5年前 评论

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

5年前 评论

头部记得引入 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

5年前 评论

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

5年前 评论