Auth::user() 使用 CORS 请求返回 null

Posted

技术标签:

【中文标题】Auth::user() 使用 CORS 请求返回 null【英文标题】:Auth::user() returns null with CORS requests 【发布时间】:2014-06-09 21:33:34 【问题描述】:

我在子域上有一个带有单独 REST API 的站点,例如api.mysite.com,我向其发送 CRUD 请求。 API 子域具有此过滤器,将适当的标头添加到响应中:

// Simple CORS handling
Route::filter('cors', function($route, $request, $response) 
    $origin = Request::header('Origin');
    $host = parse_url($origin, php_URL_HOST);

    // Don't send response for external domains.
    if (!in_array($host, Config::get('domains'))) 
        App::abort();
    

    $response->headers->set('Access-Control-Allow-Origin', $origin);
    $response->headers->set('Access-Control-Allow-Headers', 'Accept, Accept-Encoding, Accept-Language, Content-Length, Content-Type');
    $response->headers->set('Access-Control-Allow-Methods', 'DELETE, GET, PATCH, POST, PUT');
    $response->headers->set('Access-Control-Allow-Credentials', 'true');
);

我还在我的 jQuery $.ajax 请求中设置了 crossdomain: truexhrFields: withCredentials: true 。请求设法通过服务器,到达适当的路由等,但身份验证过程出现问题。每次,Laravel 都好像用户没有登录一样,导致对 Auth::user() 的请求返回 null。检查 Firebug 中的请求显示 Cookie 标头在请求中发送,并带有 Laravel 会话 ID,但服务器以 SetCookie 响应,就好像尝试启动一个新会话一样。我可能在这里做一些愚蠢的事情,但我正在努力确定什么

更新:通过一些调试,我发现了一些有趣的东西。还不知道是什么意思。要访问相关页面,用户必须登录。因此,当页面加载时,浏览器中有一个 laravel_session cookie。然后我通过与页面交互发送几个(跨域)AJAX 请求。第一个请求根本没有设置 cookie,并从服务器获取一个新的 laravel_session cookie 集。然后第二个请求包含该 cookie,但对它的响应会发送回另一个新 cookie,就好像后端从未收到关于第一个的备忘录一样。我开始怀疑这是否与 cookie 域或类似的东西有关。

【问题讨论】:

【参考方案1】:

我终于明白了。

首先,xhr 和路由过滤器都配置正确。这个问题的根本原因肯定是 cookie 问题。

最初没有设置 laravel_session 的 cookie 域。浏览器将其解释为“当前域”的简写。也就是 app.mysite.com 我需要做的就是在 Laravel 的session.domain 配置中显式设置值是“.mysite.com”,这样,app.mysite.com、api 就可以使用同一个会话 cookie。 mysite.com 和 mysite.com 的任何其他子域问题已解决!

也就是说,我在解决这个问题的过程中遇到了两个问题:

首先是无法为 TLD 设置 cookie。我通常将我的开发域设置为类似于“mysite”的内容,而不使用 TLD。就 DNS 而言,这是一个 TLD,cookie 将失败。一旦我将用于开发的虚假域更改为“mysite.dev”,“mysite”就不再是 TLD,并且浏览器接受了它的 cookie。 第二个问题是,我必须先从浏览器中删除会话 cookie,然后才能登录到新的不同域。我不知道为什么会这样,但请记住在执行此操作时清除会话 cookie。 显然,要求您的用户做这件事太多了。如果您要将此类更改放入已部署的站点,则需要考虑如何让您的用户迁移到 cookie 更改。 由于 Laravel 会话 cookie 的到期时间设置在不久的将来,一种选择是在您的用户不是很活跃时简单地部署此类更改,并接受似乎已损坏的应用程序,直到所有会话 cookie 都已过期。只有您当前和最近活跃的用户会受到影响,并且“解决方案”既好又简单。但是您的应用有一段时间坏了。 另一个选项是在更改 cookie 域的同时将会话 cookie 的名称从“laravel_session”中更改。这样一来,新 cookie 就位于旧 cookie 旁边,而旧 cookie 过期,您的应用不会中断。

【讨论】:

我在这个问题上遇到了麻烦。我正在从 localhost:9000 在 localhost:8000 与我的 laravel 服务器交互。 laravel_session cookie 是否存储经过身份验证的用户? 它只是一个用于查找会话的哈希。如果我没记错的话,经过身份验证的用户仅作为 ID 存储在会话中。如果您尝试使用 Auth::user();,则会从数据库中获取实际的用户记录

以上是关于Auth::user() 使用 CORS 请求返回 null的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS $http 从失败的 CORS 请求返回状态码 0

Laravel Auth::user()->id 在 livewire 表单上返回 null

CORS 预检请求返回“403 Forbidden”;随后的请求,然后仅在 Chrome 中发送

即使服务器返回适当的响应标头,Firefox 也不允许 CORS 请求

为啥一些跨域 XMLHttpRequest 请求不返回 CORS 错误

Angular 跨域请求 CORS 失败,但节点 http.get() 成功返回