【问题标题】:Set and Check Cookie in the one response - Laravel在一个响应中设置和检查 Cookie - Laravel
【发布时间】:2015-04-25 00:44:09
【问题描述】:

我正在尝试设置 cookie,然后检查是否已设置 cookie。

所以在一个函数中,我让它制作 cookie:

public function makeCookies(){
    Cookie::queue('logged_in', $value, 15);
    Cookie::queue('user_id', 2);
    //return Response::make()->withCookie(Cookie::make('logged_in', $value, 15))->withCookie(Cookie::forever('user_id', 2));
}

在另一个函数中,我尝试检查 cookie 是否已设置:

public function checkCookies(){
         $this->makeCookies();
         if(Cookie::get('logged_in') && Cookie::get('user_id')){
              return 'Logged In!';
         }
}

但是,唯一可行的方法是在 $this->makeCookies(); 之前添加“return”。但是,我希望能够达到它下面的条件。我有什么办法可以做到这一点?非常感谢任何帮助。

【问题讨论】:

    标签: php laravel cookies laravel-4


    【解决方案1】:

    要了解 Cookie 创建/读取过程:

    1. 用户的浏览器发送一个页面请求,以及它当前为该站点拥有的所有 cookie
    2. 网站提供页面,您创建的任何 cookie 都将成为响应中的标题。
    3. 对您网站的后续请求将发送在 #2 中创建的 cookie。

    您的要求...能够读取您在第 1 步中的第 2 步中创建的 cookie...不可能。

    现在,根据 Cookie 类的创建方式,您可以在调用 Cookie::queue() 时创建内存数据,以反映 cookie 在下一次“应该”是什么请求,但它并不真正知道用户的浏览器是否会接受 cookie 等。

    这就是为什么许多网站在创建 cookie 后会给用户重定向到带有类似 ?checkCookie=1 的页面的原因。这样,在后续请求中,他们可以验证您的浏览器是否支持 cookie……如果 ?checkCookie 页面上不存在 cookie,他们会给您一个错误,说明他们的站点需要 cookie 支持。但是,它确实需要对服务器进行第二轮从创建的浏览器中读取 cookie。

    更新 2015-04-24 根据 @Scopey,Laravel 确实支持通过 queued() 在内存中检索 cookie。所以,你应该能够做到:

    public function checkCookies(){
        $this->makeCookies();
        $loggedIn = Cookie::get('logged_in') ?: Cookie::queued('logged_in');
        $userId   = Cookie::get('user_id') ?: Cookie::queued('user_id');
        if( $loggedIn && $userId ){
            return 'Logged In!';
        }
    }
    

    安全问题(未直接回答问题)

    你的问题只是关于 cookie 的,所以我回答的就是这些。但是,既然我正在查看您的代码,我觉得如果我没有为碰巧正在阅读此内容的任何人指出这一点,我会失职。这可能只是您自己的“操作方法”,而不是生产代码,但如果该代码公开,可能会非常危险。

    确保您不信任存储在 cookie 中的 user_id 来确定通过 cookie 进入的用户。如果您依赖它,并且我访问您的网站,我可以将我的 cookie 修改为我想要的任何 user_id 并进入其他人的帐户。

    一般安全规则:

    cookie 应包含 GUID 或类似的随机字符串来标识会话。这个随机字符串应该足够长(例如 32 个字符或更长,恕我直言),这样某人就不容易强行劫持会话。

    user_id 应该存储在 $_SESSION(或 laravel 的 session 包装器,如果适用)中,这样用户就无法访问 user_id 来修改它。

    在普通 PHP 中,登录页面是这样的:

    session_start();
    if( isValidPassword($_POST['username'], $_POST['password']) ) {
        $_SESSION['user_id'] = $user->Id;
    }
    else {
        die('invalid login credentials');
    }
    

    session_start() 方法会自动为用户生成一个带有随机长字符串的 cookie(因此您甚至不必担心那部分。)

    在随后的页面上,您只需检查会话 user_id 即可知道谁登录了:

    session_start();
    if( empty($_SESSION['user_id']) ) {
        die('You are not logged in and cannot access this page');
    }
    

    根据 Laravel 的文档根据需要进行更改,如果他们有自己的会话包装器,我确信在最佳实践方面有很好的记录。

    【讨论】:

      【解决方案2】:

      @KevinNelson 对 cookie 的出色描述,但 Laravel 确实支持取回您在当前请求中排队的任何 cookie。尝试使用

      Cookie::queued('logged_in');
      

      问题是,cookie 只会在您将其排队的请求期间“排队”。您必须像处理任何其他请求一样使用get

      【讨论】:

      • 谢谢你!官方文档描述了queue(),但没有描述queued(),所以很难找到。
      猜你喜欢
      • 2012-10-14
      • 1970-01-01
      • 2011-09-05
      • 1970-01-01
      • 2021-06-30
      • 1970-01-01
      • 2015-07-23
      • 1970-01-01
      • 2012-03-25
      相关资源
      最近更新 更多