Auth :: user()返回带有CORS请求的null

时间:2014-04-24 14:19:14

标签: laravel cors

我的子网站上有一个单独的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 crossdomain: true请求中设置了xhrFields: { withCredentials: true }$.ajax。请求设法通过服务器,访问适当的路由等,但身份验证过程出现问题。每次,Laravel就像用户没有登录一样,导致Auth::user()的请求返回null。检查Firebug中的请求显示,Cookie标头在具有Laravel会话ID的请求中发送,但服务器以SetCookie响应,就像尝试启动新会话一样。我可能在这里做了一些愚蠢的事情,但我最终想要确定是什么

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

1 个答案:

答案 0 :(得分:3)

我终于明白了。

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

laravel_session的cookie域最初未设置。浏览器将其解释为“当前域”的简写。也就是说,app.mysite.com我需要做的是将Laravel的session.domain配置中的值明确设置为“.mysite.com”这样,app.mysite.com可以使用相同的会话cookie, api.mysite.com,以及mysite.com的任何其他子域问题解决了!

也就是说,我在前往这个解决方案时遇到了两个陷阱:

  • 首先是无法为TLD设置cookie。我通常将我的开发域设置为类似“mysite”的东西,而不是TLD。就DNS而言,这是一个TLD,而cookie将失败。一旦我将我的虚假域名改为“mysite.dev”,“mysite”就不再是顶级域名,浏览器也接受了它的cookie。
  • 第二个是我必须先从浏览器中删除会话cookie,然后才能登录到新的不同域。我不知道为什么会出现这种情况,但请记住在执行此操作时清除会话cookie。
    • 显然,要求用户这样做太过分了。如果您将此类更改放入已部署的站点中,则需要考虑如何将用户迁移到Cookie更改。
    • 由于Laravel会话cookie设置的过期时间不会太远,一种选择是在用户不活跃时简单地部署此类更改,并接受看似在所有会话cookie过期之前被破坏的应用程序。只有您当前和最近活跃的用户才会受到影响,“解决方案”非常简单。但是你的应用程序已经破了一段时间。
    • 另一个选项是在更改cookie域的同时更改会话cookie的名称,使其远离“laravel_session”。这样,新的Cookie就位于旧的Cookie旁边,而旧的Cookie会过期,您的应用仍然保持不间断。