Подтвердить что ты не робот

Проблема Axios CORS с Github oauth Не получать токен доступа

Я создал 2 маршрута в своем приложении React-Redux. Я уже добавил настройки приложений github с домашней страницей и URL обратного вызова.

1. При переходе по этому маршруту: https://reduxapp.herokuapp.com/signin. Вы нажимаете кнопку входа в Github, ==> githubGeturi.

2. Github перенаправляет обратно с кодом https://reduxapp.herokuapp.com/auth/callback?code=9536286a59228e7784a1 и githubSendCode ('9536286a59228e7784a1') запускается действие

Вы можете видеть, что в сетевом вызове OPTIONS вызов проходит, но вызов POST никогда не происходит. и вы получите ошибку консоли:

XMLHttpRequest cannot load https://github.com/login/oauth/access_token?client_id=32b70bf671e04762b26c&…_secret=123456789123456789123456789&code=9536286a59228e7784a1. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://reduxapp.herokuapp.com' is therefore not allowed access.

Ниже приведены мои действия функции:

const CLIENT_ID = '32b70bf671e04762b26c';
const CLIENT_SECRET = '123456789123456789123456789';
const ROOT_URL = window.location.origin;
const REDIRECT_URL = '${ROOT_URL}/auth/callback';
const AUTHORIZE_URL = 'https://github.com/login/oauth/authorize';
const ACCESS_TOKEN_URL = 'https://github.com/login/oauth/access_token';
const STATE = _.random(10000);

export function githubGeturi() {
  const GITHUB_URL = '${AUTHORIZE_URL}?client_id=${CLIENT_ID}&scope=user,public_repo&redirect_uri=${REDIRECT_URL}';

  return (dispatch) => dispatch(signinUrl(GITHUB_URL));
}

export function githubSendCode(code) {
  const GITHUB_URL = '${ACCESS_TOKEN_URL}?client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}&code=${code}';

  axios.defaults.headers.post['Access-Control-Allow-Origin'] = '*';
  const axiosPost = axios.post(
    GITHUB_URL,
    {
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      'Accept': 'text/json'
    }
  });

  return (dispatch) => {
    dispatch(signinRequest());
    return axiosPost
      .then(
        success => dispatch(signinSuccess(success)),
        error => dispatch(signinError(error))
      );
  };
}

======== Единственный возможный способ, который я нашел, это сделать POST-вызов с сервером. Вы можете просмотреть полное решение здесь: https://github.com/steelx/ReduxWeatherApp/commit/6215634ca543a4760ea96397fe31b61f22184d91

4b9b3361

Ответ 1

Похоже, вы не можете позвонить в эту конечную точку через JavaScript

https://github.com/isaacs/github/issues/330

В вашем примере я вижу, что вызов метода OPTIONS терпит неудачу, и это происходит потому, что axios делает это, когда вы добавляете дополнительные заголовки для запроса, но POST-вызов также терпит неудачу.

Вы можете настроить прокси-сервер между вашим приложением и github на своем сервере, который просто перенаправляет ваши запросы и отвечает с ответом.

Ответ 2

На самом деле проблема заключается в вызове ОПЦИИ. если вы добавите какой-либо дополнительный заголовок к вызову API, тогда произойдет первый вызов API OPTIONS, а затем будет выполнен пост-вызов. Так что если хотите с этим справиться. Есть решение. Вы можете написать фильтр, внутри которого вы должны проверить опцию call api call и вернуть статус 200 Ok. Ниже приведен пример кода.

пакет com.web.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.catalina.connector.Response;

public class CustomFilter implements Filter {
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest httpRequest = (HttpServletRequest) req;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with, Content-Type");
        if (httpRequest.getMethod().equalsIgnoreCase("OPTIONS")) {
            response.setStatus(Response.SC_OK);
        }
        chain.doFilter(req, res);
    }

    public void init(FilterConfig filterConfig) {
        // TODO
    }

    public void destroy() {
        // Todo
    }

}