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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在浏览器中调用oAuth2 api时出现404错误相关的知识,希望对你有一定的参考价值。

我在rails上使用ruby来制作RESTful api,还使用了doorkeeper来处理身份验证和授权。如你所知,门卫会生成一些OAuth2 api,而我需要使用的两个是/ users,这是post请求和/ oauth / token为我做的令牌。我做的api是post,get,put在postman和android studio以及web浏览器中工作。但由门卫生成的后api / users和/ oauth / token在网络浏览器中不起作用,但在android studio和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
答案

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

另一答案

在检查了他们的docs之后,看起来你需要将Content-Type标题更改为application/x-www-form-urlencoded并将数据更改为key=value对:

const data = 'username=1&password=password&grant_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响应中的日志或错误消息。

另一答案
    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;
        });

}

以上是关于在浏览器中调用oAuth2 api时出现404错误的主要内容,如果未能解决你的问题,请参考以下文章

使用移动浏览器请求自定义帖子类型时出现 Wordpress REST API 404 错误

Postman调用动态o365 web api时出现403 Forbidden错误

使用 Gitlab API 添加 SSH 密钥时出现 Http 404 错误

从泽西客户端调用 post API 时出现 415 错误

从链接调用另一个 JSP 时出现 404 错误

ExpressJS Node.js Angular 错误:获取 OAuth2 API 授权令牌时出现 getaddrinfo ENOTFOUND