教你修改 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 的过期时间了.

本帖由系统于 1年前 自动加精
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 6

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

2年前 评论

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

2年前 评论

先mark,:+1:

2年前 评论

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

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

10个月前 评论

mark住一波

3周前 评论

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

2周前 评论

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!