Как победить OPTIONS при CORS?

Вот который день пытаюсь победить CORS.
Есть проект, который вертиться на localhost и с него обращаюсь к REST
Перешуршал весь интернет, вроде все хедеры на обеих сторонах правильно указаны (Authorization Bearer), но не работает.
Во время отправки запроса на сервер первым делом отправляется OPTIONS (после чего, насколько я понимаю из документации, должен последовать POST, но этого не происходит). OPTIONS отправляется, статус 200 и у него есть response. Вот если перезагрузить страницу, то тогда уже отправляются POST запросы.
Кто знает варианты решения проблемы?
  • Вопрос задан
  • 3003 просмотра
Решения вопроса 2
astec
@astec
Разработчик https://debtstracker.io/
Только вчера разбирался для своего проекта по учёту долгов https://debtstracker.io/ и победил.

На OPTIONS надо возвращать 200 с заголовками и пустой ответ.

Я руководствовался этой схемой:
cors_server_flowchart.png

Вот мой работающий код на Go:

func getOnly(handler HttpHandler) HttpHandler {
	return func(w http.ResponseWriter, r *http.Request) {
		c := appengine.NewContext(r)
		if r.Method == "OPTIONS" {  // Preflight request
			origin := r.Header.Get("Origin")
			switch origin {
			case "http://localhost:8080":
			case "http://localhost:8100":
			case "https://debtstracker.local":
			case "https://debtstracker.io":
			case "":
				BadRequest(c, w, errors.New("Missing required request header: Origin"))
				return
			default:
				err := errors.New(fmt.Sprintf("Unknown origin: %v", origin))
				log.Debugf(c, err.Error())
				BadRequest(c, w, err)
				return
			}
			log.Debugf(c, "Request 'Origin' header: %v", origin)
			if accessControlRequestMethod := r.Header.Get("Access-Control-Request-Method"); accessControlRequestMethod != "GET" {
				BadRequest(c, w, errors.New("Not a valid preflight request"))
				return
			}
			responseHeader := w.Header()
			responseHeader.Set("Access-Control-Allow-Methods", "GET")
			if accessControlRequestHeaders := r.Header.Get("Access-Control-Request-Headers"); accessControlRequestHeaders != "" {
				log.Debugf(c, "Request Access-Control-Request-Headers: %v", accessControlRequestHeaders)
				responseHeader.Set("Access-Control-Allow-Headers", accessControlRequestHeaders)
			} else {
				log.Debugf(c, "Request header 'Access-Control-Allow-Headers' is empty or missing")
				// TODO(security): Is it wrong to return 200 in this case?
			}
			responseHeader.Set("Access-Control-Allow-Origin", origin)
			w.WriteHeader(200)
			return
		}
		if r.Method != "GET" {
			BadRequest(c, w, errors.New(fmt.Sprintf("Expecting to get request method GET, got: %v", r.Method)))
			return
		}
		handler(w, r)
	}
}
Ответ написан
@davidnum95
Касательно YII2 в базовом контроллере нужно указать поведение для CORS:
public function behaviors()
    {
        return [
            'corsFilter' => [
                'class' => Cors::className(),
            ],
            'authenticator' => [
                'class' => HttpBearerAuth::className(),
                'except' => ['options'],
            ],
        ];
    }
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы