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

时间:2017-11-11 07:14:42

标签: javascript ruby-on-rails ruby reactjs doorkeeper

我在rails上使用ruby来制作RESTful api,还使用了门卫来处理身份验证和授权。如你所知,门卫会生成一些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:

y >= 5

并且还使用原始jQuery来发出请求并获得相同的错误。所有我的api都很好地执行了这两个api:

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));
        });

此代码console.log的输出(JSON.stringify(error));是这样的:

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);

我在浏览器中找到请求标头和响应标头:

{"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":{}}

4 个答案:

答案 0 :(得分:1)

检查完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));
});

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

    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;
        });

}