2017-09-11 58 views
0

我试图使用rails api-ony应用程序作为后端,并将React js作为前端。我使用axios发送/接收请求。最初我甚至无法登录,然后大量使用谷歌搜索我遇到this gem它是关于CORS,它解决了我的POST请求错误。
我能够成功登录,当我在Rails应用程序中做POST请求,并且我得到了令牌(它适用于POSTMAN应用程序)。现在,当我做GET请求并将该令牌作为标题传递给使用反应应用程序时,它继续给我401 Unauthorized error,然后在多次使用Google搜索后,我看到了this SO post。它没有解决这个问题。我错过了什么?请关注这个问题的原因。
这是application_controller.rb:401当使用React时rails api-only应用程序中的未授权错误

class ApplicationController < ActionController::API 
    include ActionController::MimeResponds 

    before_action :authenticate_request, :current_user, :cors_preflight_check 
    attr_reader :current_user 

    #before_filter :current_user, :cors_preflight_check 
    after_action :cors_set_access_control_headers 

# For all responses in this controller, return the CORS access control headers. 

def cors_set_access_control_headers 
    headers['Access-Control-Allow-Origin'] = '*' 
    headers['Access-Control-Allow-Methods'] = 'POST, PUT, DELETE, GET, OPTIONS' 
    headers['Access-Control-Request-Method'] = '*' 
    headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization' 
    headers['Access-Control-Max-Age'] = "1728000" 
end 

# If this is a preflight OPTIONS request, then short-circuit the 
# request, return only the necessary headers and return an empty 
# text/plain. 

def cors_preflight_check 
    if request.method == :options 
     headers['Access-Control-Allow-Origin'] = '*' 
     headers['Access-Control-Allow-Methods'] = 'POST, PUT, DELETE, GET, OPTIONS' 
     headers['Access-Control-Request-Method'] = '*' 
     headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization' 
    headers['Access-Control-Max-Age'] = '1728000' 
    render :text => '', :content_type => 'text/plain' 
    end 
end 

    require 'date' 
      require 'json' 
      require 'groupdate' 

    @@PRESENT_DATE=Date.parse('2016-12-31T00:00:00.000Z') 
    @@MONTHLY_SELECTOR="SELECT CONCAT(MONTHNAME(invoiceDate),' - ',YEAR(invoiceDate)), SUM(invoiceAmt) FROM invoices GROUP BY YEAR(invoiceDate), MONTH(invoiceDate)" 
    @@QUARTERLY_SELECTOR="SELECT SUM(invoiceAmt) AS invoiceTotal, CONCAT('Q',QUARTER(invoiceDate), '(', YEAR(invoiceDate), ')') FROM invoices GROUP BY YEAR(invoiceDate), QUARTER(invoiceDate) ORDER BY YEAR(invoiceDate), QUARTER(invoiceDate)" 
    @@YEARLY_SELECTOR="SELECT SUM(invoiceAmt) AS invoiceTotal, YEAR(invoiceDate) AS Year FROM invoices GROUP BY YEAR(invoiceDate) ORDER BY YEAR(invoiceDate)" 

    private 

    def authenticate_request 
     @current_user = AuthorizeApiRequest.call(request.headers).result 
     render json: { error: 'Not Authorized' }, status: 401 unless @current_user 
    end 
end 

在我反应过来的应用程序我有这样的:

import React, { Component } from 'react'; 
import '../App.css'; 
var axios = require('axios'); 

class Login extends Component { 
    constructor(props){ 
    super(props); 
    //this.state = {isToggleOn: true}; 
    this.loadDashboard = this.loadDashboard.bind(this); 
    this.handleOnSubmit = this.handleOnSubmit.bind(this); 
    } 

    loadDashboard(token){ 
    axios({ 
     method:'get', 
     url:'http://localhost:3000/api/dashboard', 
     Authorization: { 
     Authorization: token, 
     }, 
    }) 
    .then(function (response) { 
     console.log(response); 
    }) 
    .catch(function (error) { 
     console.log("Error in loading Dashboard "+error.response.status); 
    }); 
    } 

    handleOnSubmit =() => { 
    console.log("submittwed"); 
    axios({ 
     method:'post', 
     url:'http://localhost:3000/authenticate', 
     data: { 
     email: '[email protected]', 
     password: 'apple' 
     }, 
    }) 
     .then((response) => { 
     var token = response.data.auth_token; 
     console.log(token); 
     this.loadDashboard(token); 
     }) 
     .catch(function (error) { 
     console.log("Error in login "+error); 
     }); 
    } 

    render() { 
    return (
     <div> 
     Username: <input type="email" name="fname" /><br /> 
     Password: <input type="password" name="lname" /><br /> 
     <button onClick={this.handleOnSubmit}>LOG IN</button> 
     </div> 
    ); 
    } 
} 

export default Login;  

完整标题响应:

Request URL:http://localhost:3000/api/dashboard 
Request Method:GET 
Status Code:401 Unauthorized 
Remote Address:127.0.0.1:3000 
Referrer Policy:no-referrer-when-downgrade 
Response Headers 
view source 
Access-Control-Allow-Methods:GET, POST, OPTIONS 
Access-Control-Allow-Origin:* 
Access-Control-Expose-Headers: 
Access-Control-Max-Age:1728000 
Cache-Control:no-cache 
Content-Type:application/json; charset=utf-8 
Transfer-Encoding:chunked 
Vary:Origin 
X-Request-Id:f78a4c29-ef9a-446c-8771-9e2b70d41757 
X-Runtime:0.045998 
Request Headers 
view source 
Accept:application/json, text/plain, */* 
Accept-Encoding:gzip, deflate, br 
Accept-Language:en-US,en;q=0.8 
Connection:keep-alive 
Host:localhost:3000 
Origin:http://localhost:3001 
Referer:http://localhost:3001/ 
User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36 

Rails的版本:5.1.3的Rails

  • 有没有人遇到类似的东西?
  • 我该如何解决这个问题?
  • 有没有更少的混乱/更好的方法?

请帮我解决这个问题。

+0

难道你不需要在'headers'键中添加'Authorization'头而不是'data'吗? – mersocarlin

+0

@HemersonCarlin我刚刚做到了。它虽然没有奏效。还更新了我的问题 – noobie

+0

请显示完整的错误响应。 401可能是各种各样的东西,但内容正文和标题通常会使其变得明显。请确保标记正确的Rails版本。你真的使用Rails 3.x? –

回答

1

您错过了发送给您的api电话的headers密钥。

axios({ 
    method:'get', 
    url:'http://localhost:3000/api/dashboard', 
    headers: { 
    Authorization: `Bearer ${token}`, 
    }, 
}) 
    .then(function (response) { 
    console.log(response) 
    }) 
    .catch(function (error) { 
    console.log("Error in loading Dashboard "+error.response.status) 
    }) 
相关问题