redirect - CORS 预检后 302 重定向

标签 redirect laravel-4 cors

在我的 CORS 预检成功返回 200 状态后,我遇到了 302 重定向问题。我目前正在使用 Laravel 4.1 和 Angular 1.2 以及我自己的 OAUTH2 服务器构建一个应用程序。

Chrome/FF/Safari 发回给我的错误是:

XMLHttpRequest cannot load http://localhost.api/api/v1/tracks?$filter=id%20eq%20guid%27d7de10ba-e353-455b-a3cb-ced9b4965141%27&. The request was redirected to 'http://localhost.api/session/invalid', which is disallowed for cross-origin requests that require preflight.

我认为导致我的问题的是正在发生的“重定向” - 因为我的正常 CORS 要求所有工作按预期进行。

我的 Access-Control-Allow-* header 的配置现在在测试期间相当开放。

  'paths' => array(
      '^/api/' => array(
          'allow_origin'=> array('*'),
          'allow_headers'=> array('Content-Type', 'Authorization'),
          'allow_methods'=> array('POST', 'PUT', 'GET', 'DELETE', 'OPTIONS'),
          'max_age' => 0     
      ),                
      '^/session/' => array(
          'allow_origin'=> array('*'),
          'allow_headers'=> array('Content-Type', 'Authorization'),
          'allow_methods'=> array('GET', 'OPTIONS'),               
          'max_age' => 0                                                        
      ) 

有问题的重定向位于检查 OAUTH2 访问 token 有效性的预过滤器中

public function filter($route, $request, $data = null)                       
{                                                                            
    //  Get the authorization header or fail                                 
    if ($authorization = Request::header('Authorization', false)) {          
        list($type, $token) = explode(' ', $authorization);                  
        if (is_null($auth = OAuth2::token($token)->first())) {               
            return Redirect::to('session/invalid');                                                              
        }                                                                    
        $tokenExpiryDate = Carbon::createFromTimeStamp($auth->access_token_expires);

        //  If we don't have a Bearer authentication header                  
        //  or if the token has expired.  Then redirect to an                
        //  expired session route                                            
        if (   'bearer' != strtolower($type)                                 
            || Carbon::now()->gt($tokenExpiryDate)                           
        ) {                                                                  
            return Redirect::route(                                          
                'expiredSession',                                            
                array('expiry' => $tokenExpiryDate->timestamp)               
            );                                                               
        }                                                                    
    } else {                                                                 
        //  The authentication header is invalid, redirect to let the user know.
        return Redirect::to('session/invalid');                              
    }                                                                        
}  

当我尝试使用 POSTMAN 进行调试时,所有这些请求都有效,但经过研究,我基本上发现扩展不一定必须遵循相同的规则。我还注意到,当我发起简单的 GET、POST 等操作时,使用 POSTMAN 的请求从不发送任何预检选项请求。

以下是 OPTIONS 请求的 header 以及跟随该请求并返回错误的 GET 请求的 header

选项请求

Remote Address:127.0.0.1:80 
Request URL:http://localhost.api/api/v1/tracks?$filter=id%20eq%20guid%27d7de10ba-e353-455b-a3cb-ced9b4965141%27&
Request Method:OPTIONS
Status Code:200 OK

请求 header

Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, authorization
Access-Control-Request-Method:GET
Cache-Control:no-cache
Connection:keep-alive
DNT:1
Host:vegas.ine.com
Origin:http://localhost.angular
Pragma:no-cache
Referer:http://localhost.angular/admin/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131 Safari/537.36   

响应 header

Access-Control-Allow-Headers:content-type, authorization
Access-Control-Allow-Methods:POST, PUT, GET, DELETE, OPTIONS
Access-Control-Allow-Origin:http://localhost.angular
Cache-Control:no-cache
Connection:close
Content-Type:text/html
Date:Thu, 01 May 2014 16:22:19 GMT
Server:Apache/2.2.26 (Unix) DAV/2 PHP/5.4.24 mod_ssl/2.2.26 OpenSSL/0.9.8y
Set-Cookie:laravel_session=eyJpdiI6IktOZjlTM1ZVNUx0TEhoaTczY3dQcDBKRWlvbnppbDA3QTdqSENJdTc2R1U9IiwidmFsdWUiOiJEZ2ltXC9mNm1Qa20rV3BVRlNHTXgySGtUeVlpNjNZcGFudDFBWDJJekl1MEVNVlhSRE5WWk5YZDNxUkZuU0VEVytcL3NLNlVBXC9hZWtJQzdHU2FqVWtMdz09IiwibWFjIjoiYTYxYjEwNjlmYmI2MjMwNmE4MzlkYjIwNGZlNzA4Y2ViZGVkZmU1MTQzMzc5NmU2YzI2ZGExNzYxY2U5ZjdiMCJ9; expires=Thu, 01-May-2014 18:22:19 GMT; path=/; httponly
X-Frame-Options:SAMEORIGIN
X-Powered-By:PHP/5.4.24  

获取请求

Remote Address:127.0.0.1:80
Request URL:http://localhost.api/api/v1/tracks?$filter=id%20eq%20guid%27d7de10ba-e353-455b-a3cb-ced9b4965141%27&
Request Method:GET
Status Code:302 Found

请求 header

Accept:application/json, text/plain, */*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Authorization:Bearer 6Ss4XPrPM5jQD7Es0dz7TPRQ76hGA69vT9K94pst
Cache-Control:no-cache
Connection:keep-alive
DNT:1
Host:vegas.ine.com
Origin:http://localhost.angular
Pragma:no-cache
Referer:http://localhost.angular/admin/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131 Safari/537.36

响应 header

Access-Control-Allow-Origin:http://localhost.angular
Cache-Control:no-cache
Connection:Keep-Alive
Content-Type:text/html; charset=UTF-8
Date:Thu, 01 May 2014 16:22:19 GMT
Keep-Alive:timeout=5, max=100
Location:http://localhost.api/session/invalid
Server:Apache/2.2.26 (Unix) DAV/2 PHP/5.4.24 mod_ssl/2.2.26 OpenSSL/0.9.8y
Set-Cookie:laravel_session=eyJpdiI6InlnREVPcUJTcyswMnRLanFDSlZ6QWFBVXZWMGdMNVNLYWxNTHRJVUlkalk9IiwidmFsdWUiOiJ4aXN5U0dcL1NYeGQrcUVzWFhYV3o2MWhcL25hQTlhcVUxbWxkN2R6SG9KZDNKaGNLTkRQY2FyTitpVHNGZzYxVVRtZUhoZGZRWE9GWjZRaDd1VVwvZUZuUT09IiwibWFjIjoiY2EzZTViZGIzZmVlMDcwZjdhMzBjOWQxYTgwZWNlYTJiMDk3ODdlZTk3NTYxMDNmM2YyODJjOGIxMzBmMmJlMiJ9; expires=Thu, 01-May-2014 18:22:20 GMT; path=/; httponly
Transfer-Encoding:chunked
Vary:Authorization
X-Clockwork-Id:1398961340.2239.1349476325
X-Clockwork-Version:1.5
X-Frame-Options:SAMEORIGIN
X-Powered-By:PHP/5.4.24

最佳答案

我做过类似的事情,它对我来说效果很好

//pattern to allow origins
$allowedOriginPattern = /** YOUR PATTERNS **/;
$allowedOrigin = "";
if (preg_match($allowedOriginPattern, $_SERVER['HTTP_ORIGIN'])) {
    $allowedOrigin = $_SERVER['HTTP_ORIGIN'];
}

/**
 * set http content type
 */
header('Content-Type: application/json;charset=UTF-8');
header('Access-Control-Allow-Origin: ' . $allowedOrigin);
header('Access-Control-Allow-Methods: DELETE, HEAD, GET, OPTIONS, POST, PUT');
header('Access-Control-Allow-Headers: Content-Type, Content-Range, Content-Disposition, Content-Description');
header('Access-Control-Max-Age: 1728000');

我已在 laravel index.php 中添加了此代码

这里是CORS的引用 http://www.w3.org/TR/cors/#cross-origin-request-with-preflight-0

关于redirect - CORS 预检后 302 重定向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23412037/

相关文章:

bash - 为什么使用 2>&1 指令重定向 stderr 失败?预计产出如何发挥作用?

linux - Simle 重定向报告没有这样的文件或目录

python - Angular $http 正在发送 OPTIONS 而不是 PUT(不是 POST)

jquery - 泽西 REST + CORS + Jquery AJAX 调用

在 example.com 上没有有效证书的情况下,从 https ://example. com 重定向到 https ://www. example.com

mod-rewrite - mod_rewrite : redirect to a folder with the same name as domain

php - Laravel 检查是否违反约束

php - 使用 Laravel 将 CSV 文件上传到 MySQL

php - Laravel 4 - 选择相关模型

javascript - 已部署 - 通过 AngularJS CORS 检索的数据