2017-09-11 4 views
0

레일 엔드 api-ony 앱을 백엔드로 사용하고 React js를 프런트 엔드로 사용하려고합니다. axios를 사용하여 요청을 보내고받습니다. 처음에 나는 심지어 많은 인터넷 검색 후 로그인 할 수 없었다. this gem 그것은 CORS에 관한 것이었다. POST 요청 오류가 해결되었다.
레일 앱에서 POST 요청을했을 때 성공적으로 로그인 할 수 있고 답례로 토큰을 받고 있습니다 (POSTMAN 앱에서는 잘 작동합니다). 자, 내가 GET 요청을하고 그 토큰을 반응 앱을 사용하여 Header로 넘길 때, 401 Unauthorized error을 계속 유지하고, 많은 인터넷 검색을 한 후에 다시 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 

내 반응 응용 프로그램 I가이 :

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 

레일 버전 : 5.1.3 레일

  • 다른 사람이 비슷한 것을 직면 했습니까 ??
  • 어떻게 해결할 수 있습니까?
  • 덜 어수럽거나 더 나은 접근법이 있습니까?

제발 도와주세요.

+0

''data' 대신'header' 키에'Authorization' 헤더를 추가 할 필요가 없습니까? – mersocarlin

+0

@HemersonCarlin 방금했습니다. 그러나 그것은 효과가 없었습니다. 또한 내 질문 업데이트 – noobie

+0

전체 오류 응답을 표시하십시오. 401은 여러 가지 일 수 있지만 콘텐츠 본문과 헤더는 일반적으로이를 분명하게 만듭니다. 정확한 레일즈 버전에 태그를 달아주세요. Rails 3.x를 사용하고 있습니까? –

답변

1

API 호출에 보낼 headers 키가 없습니다.