Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/402.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在浏览器中调用oAuth2 api时出现404错误_Javascript_Ruby On Rails_Ruby_Reactjs_Doorkeeper - Fatal编程技术网

Javascript 在浏览器中调用oAuth2 api时出现404错误

Javascript 在浏览器中调用oAuth2 api时出现404错误,javascript,ruby-on-rails,ruby,reactjs,doorkeeper,Javascript,Ruby On Rails,Ruby,Reactjs,Doorkeeper,我使用RubyonRails制作RESTfulAPI,还使用doorkeeper处理身份验证和授权。正如您所知,门卫生成了一些OAuth2API,我需要使用的两个api是/users,它是post请求和/oauth/token,它们为我生成了token。我制作的api是post、get、put,它在postman、android studio和web浏览器中非常有效。 但是门卫生成的postapi/users和/oauth/token在web浏览器中不起作用,但在androidstudio和po

我使用RubyonRails制作RESTfulAPI,还使用doorkeeper处理身份验证和授权。正如您所知,门卫生成了一些OAuth2API,我需要使用的两个api是/users,它是post请求和/oauth/token,它们为我生成了token。我制作的api是post、get、put,它在postman、android studio和web浏览器中非常有效。 但是门卫生成的postapi/users和/oauth/token在web浏览器中不起作用,但在androidstudio和postman上效果很好。 这让我感到困惑。调用此api时出现的错误是404,我检查了服务器上的ruby生产日志,它显示没有路由匹配。这里的字符串是方法和路由的类型是正确的

这是我在reactjs中使用的代码。我使用了axios:

var url="http://x.x.x.x/oauth/token";
    axios.post(url,{
        "username":"1",
        "password":"password",
        "grant_type":"password"
      },{headers:{"Content-Type":"application/json"}}).then( (response) => {
          console.log(response.data);
        })
        .catch( (error) => {
          console.log(JSON.stringify(error));
        });
并且还使用原始jQuery发出请求并得到相同的错误。我所有的api都可以很好地执行这两个api:

var firstname = document.forms["registerForm"]["first_name"].value;
    var lastname = document.forms["registerForm"]["last_name"].value;
    var pass = document.forms["registerForm"]["password"].value;
    var passconfirm = document.forms["registerForm"]["password_confirmation"].value;


    var json_data = {
        "async": true,
        "crossDomain": true,
        "url": send,
        "method": "POST",
        "headers": {
            "content-type": "application/json",
        },
        "processData": false,
        "data":
        {
            "user": {
                "user_name": username,
                "password": pass,
                "password_confirmation": passconfirm,
                "user_type": "admin"
            },
            "profile": {
                "first_name": firstname,
                "last_name": lastname
            }
        }
    }

    $.ajax(json_data).done(function (response) {
        console.log(response);
    });
    console.log(json_data['data']);
    console.log(username);
此代码console.log(JSON.stringify(error))的输出;这是:

{"config":{"transformRequest":{},"transformResponse":{},"timeout":0,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","maxContentLength":-1,"headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json;charset=utf-8"},"method":"post","url":"http://x.x.x.x/oauth/token.json","data":"{\"username\":\"1\",\"password\":\"password\",\"grant_type\":\"password\"}"},"request":{}}
我在浏览器中找到请求标头和响应标头:

Response Header:

Content-Type    
application/json; charset=UTF-8
Content-Length  
34
Connection  
keep-alive
Status  
404 Not Found
X-Request-Id    
d593b73f-eec8-41cd-95cd-e4459663358c
X-Runtime   
0.002108
Date    
Mon, 13 Nov 2017 11:19:26 GMT
X-Powered-By    
Phusion Passenger 5.1.11
Server  
nginx/1.12.1 + Phusion Passenger 5.1.11


Request headers (427 B) 
Host    
x.x.x.x
User-Agent  
Mozilla/5.0 (X11; Ubuntu; Linu…) Gecko/20100101 Firefox/56.0
Accept  
text/html,application/xhtml+xm…plication/xml;q=0.9,*/*;q=0.8
Accept-Language 
en-US,en;q=0.5
Accept-Encoding 
gzip, deflate
Access-Control-Request-Method   
POST
Access-Control-Request-Headers  
Origin  
http://localhost:3000
Connection  
keep-alive
在检查它们之后,您似乎需要将
内容类型
标题更改为
application/x-www-form-urlencoded
,数据为
key=value
对:

const data='username=1&password=password&grant\u type=password'

或者简单地说:

const formData = {
  username: '1',
  password: 'password', 
  grant_type: 'password',
}

const data = Object.keys(formData)
  .map(prop => `${prop}=${formData[prop]}`)
  .join('&')
最终结果将是:

var url="http://x.x.x.x/oauth/token";

axios.post(url, data, {
  headers: {
    "Content-Type": "application/x-www-form-urlencoded"
  }
}).then( (response) => {
  console.log(response.data);
})
.catch( (error) => {
  console.log(JSON.stringify(error));
});

您需要在OAuth设置中配置以允许访问客户端web应用程序。检查api响应中的日志或错误消息。

似乎是因为CORS策略。你可以。
这是一个机架中间件,您可以向受doorkeeper保护的应用程序发出跨域请求

您可以共享错误消息吗?这可能与CORS有关,您可以尝试使用var
url=”http://x.x.x.x/oauth/token.json"
?是的,我只是在我的端点的末尾添加了json,但它不起作用,也像这样编写了关于CORS的教程,并添加到我的代码中。我测试了您的方法,但不起作用,我在WWW-Authenticate中得到了响应,上面写着Bearer-realm=“Doorkeeper”,error=“invalid\u request”,error\u description=“请求缺少必需的参数,包含不受支持的参数值,或者格式不正确。”@Sandro他们的文档还提到要发送(
grant\u type
client\u id
client\u secret
code
)您是否发送这些道具?诀窍是const data=Object.keys(formData).map(prop=>
${prop}=${formData[prop]}
).join(“&”)@Sandro你找到解决方案了吗?没有,我还在搜索,senoir的一位开发人员说它可以来自doorkeeper中的回拨url,但我不知道如何在doorkeeper中配置回拨url。doorkeeper中有一些关于回拨的理论文本,但没有相关的技术文档。我真的不知道该怎么做
    function login(username, password, returnUrl) {

    const formData = {
        grant_type:"password",
        client_id:"xxxxxxxx",
        client_secret: "xxxxxxxxx",
        redirect_uri:"xxxxxxxx.com/api/v1/accounts/profile/",
        username:username,
        password:password
    }

    const d = Object.keys(formData)
      .map(prop => `${prop}=${formData[prop]}`)
      .join('&')

    const requestOptions = {
        method: 'POST',
        headers: { 
            "Content-Type": "application/x-www-form-urlencoded",
            'Accept': 'application/json'
         },
        body: d
    };

    return fetch('xxx.com/o/token/', requestOptions)
        .then(handlePostResponse)
        .then(token => {

            // login successful if there's a user in the response
            if (token) {
                token.token = token
            }

            console.log(token)

            return token;
        });

}