已完成401未授权请求被重定向到不需要预检的跨源请求

时间:2016-06-17 12:37:33

标签: ruby-on-rails angularjs devise ionic-framework cors

这个问题可能听起来像是重复的,但我已经尝试了stackoverflow上其他类似问题的所有步骤,但没有一个有效。我正在尝试使用离子连接到Rails API。

我的设置是 Rails 4,设计用于身份验证,simple_token_authentication用于基于令牌的API请求和离子用于移动应用程序。

我可以通过将具有正确用户名和密码的登录请求传递给设计会话控制器api来登录离子,并在成功登录设计api后获取令牌。

之后,当我尝试使用访问令牌使用get查询访问任何控制器的索引时: http://localhost:3002/api/categories?token=1098ccee839952491a4http://localhost:3002/api/employers?token=1098ccee839952491a4

响应是设计的sign_in页面。在rails日志中,显示

Started GET "/api/categories?token=1098ccee839952491a43" for ::1 at 2016-06-17 17:45:55 +0530
Processing by Api::CategoriesController#index as HTML
  Parameters: {"token"=>"1098ccee839952491a43"}
  User Load (0.7ms)  SELECT `users`.* FROM `users` WHERE `users`.`authentication_token` = '1098ccee839952491a43'
Completed 401 Unauthorized in 3ms (ActiveRecord: 0.7ms)


Started GET "/users/sign_in" for ::1 at 2016-06-17 17:45:55 +0530
Processing by Devise::SessionsController#new as HTML
  Rendered devise/shared/_links.html.erb (6.5ms)
  Rendered devise/sessions/new.html.erb within layouts/login (78.3ms)
Completed 200 OK in 3850ms (Views: 3847.1ms | ActiveRecord: 0.0ms)

我确定令牌是正确的,因为我已经交叉检查了数据库中的令牌。此外,我已经包含了rack-cors gem,并且它被配置为允许跨域请求的任何来源。

在我的application.rb中,cors条目看起来像这样

class Application < Rails::Application
    config.active_record.raise_in_transactional_callbacks = true

    config.middleware.insert_before 0, "Rack::Cors" do
      allow do
        origins '*'
        resource '*', :headers => :any, :methods => [:get, :post, :options]
      end
    end

  end

离子中的controllers.js中的GET请求如下所示: -

 $http({
        method: 'GET',
        headers: 
         {
            'X-XSRF-TOKEN': window.localStorage.getItem("token") ,
         },
        url: config.apiUrl+"/categories?token="+window.localStorage.getItem("token") ,
            }).then(function successCallback(response) {
                                console.log(response);

              }, function errorCallback(response) {
                $ionicPopup.alert({
                    title: 'Alert',
                    template: response.data.message,
                });
              });   

启动请求后,Chrome开发者控制台会显示以下消息

  

XMLHttpRequest无法加载   http://localhost:3002/api/categories?token=1098ccee839952491a43。该   请求被重定向到“http://localhost:3002/users/sign_in”,其中   不允许需要预检的跨源请求。

我从服务器获得的响应标头是

常规

Request URL:http://localhost:3002/api/categories?token=1098ccee839952491a43
Request Method:GET
Status Code:302 Found
Remote Address:[::1]:3002

响应标题

view source
Access-Control-Allow-Credentials:true
Access-Control-Allow-Methods:GET, POST, OPTIONS
Access-Control-Allow-Origin:http://localhost:8100
Access-Control-Expose-Headers:
Access-Control-Max-Age:1728000
Cache-Control:no-cache
Connection:Keep-Alive
Content-Length:101
Content-Type:text/html; charset=utf-8
Date:Fri, 17 Jun 2016 12:26:13 GMT
Location:http://localhost:3002/users/sign_in
Server:WEBrick/1.3.1 (Ruby/2.2.1/2015-02-26)
Set-Cookie:_backend_session=c05LRTgzdXNVdGNFeHcwaDNtRDkxZ1RBbXFNaDFNbE1zMTV6OGhFZG1VODdON2k4ODN0ZTg3YXo5OU5hOTZkcUNmR3VTaGVRQzBOUElCNnMrODhnemVCbUhQbUs2azNHdmVnbFpoL2JiRDA5S1I4NCtsVWNhOEpqeDdoYWxXR3hHNDg5RzNRcUlpcDZ4QWswY2NmUlpYbUkvTnpaVEViNXh6ZExCZkNyTXA0allMcW1RVGg1MjRLVnpEbzlSSVk4dGRUSTNsTUZFNEFOcVJxdm1hWXNaSFEzdnlSN01DZ2FTdEJYUTdUUGxucU44cFBMbDZ6RXlhVUx2ZHArWlNCVWgyTWs2emRrSXNGbTQ3ZVVQL0NCR0E9PS0tbmFzajFXZnZnd25oUkRFRjhxSy81QT09--281b2bd6413653ca006abc80f13329d6bf3ad0f5; path=/; HttpOnly
Vary:Origin
X-Content-Type-Options:nosniff
X-Frame-Options:SAMEORIGIN
X-Request-Id:3097ec28-6d55-4c70-90c9-de221b4321e3
X-Runtime:0.021444
X-Xss-Protection:1; mode=block

请求标题

view source
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Host:localhost:3002
Origin:http://localhost:8100
Referer:http://localhost:8100/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.84 Safari/537.36
X-XSRF-TOKEN:1098ccee839952491a43

2 个答案:

答案 0 :(得分:0)

试试这个

app.config(function($sceDelegateProvider) {
 $sceDelegateProvider.resourceUrlWhitelist([
    // Allow same origin resource loads.
    'self',
    // Allow loading from our assets domain.  Notice the difference between * and **.
    'http://localhost:3002/**'
  ]);

});

浏览器会自动从您需要允许域的陌生人网址中获取资源。

答案 1 :(得分:0)

我认为问题与Access-Control-Allow-Credentials:true标题有关,请尝试以下方法:

$http({
        method: 'GET',
        withCredentials: true,
        headers: 
         {
            'X-XSRF-TOKEN': window.localStorage.getItem("token") ,
         },
        url: config.apiUrl+"/categories?token="+window.localStorage.getItem("token") ,
            }).then(function successCallback(response) {
                                console.log(response);

              }, function errorCallback(response) {
                $ionicPopup.alert({
                    title: 'Alert',
                    template: response.data.message,
                });
              });   

它也会向api服务器发送cookie