2015-06-07 5 views
4

Я только что попробовал добавить эту обертку (-> routes (wrap-ssl-redirect)) для автоматического перенаправления http на https, но когда я развернусь в heroku, https:// не станет зеленым в моем браузере, и веб-сайт не загружается.Clojure: wrap-ssl-redirect on heroku?

Не является ли по умолчанию порт героя 443, который также должен быть по умолчанию от wrap-ssl-redirect?

Что не так?

Спасибо!

EDIT:

Мой код:

(defn prod-app [routes] 
    (-> routes 
     (wrap-keyword-params) 
     (wrap-params) 
     (wrap-ssl-redirect))) 

(defn -main [] 
    (let [port (Integer/parseInt (get (System/getenv) "PORT" "5000"))] 
    (jetty/run-jetty (prod-app domain-specific-routes) 
        {:port port :join? false}))) 

EDIT 2:

Я только что нашел эту нить, которая может решить мою проблему: Clojure/Noir: Force HTTPS, redirect if the request was http:// to https://

придумал этот require-https обработчик Fn :

(defn https-url [request-url] 
    (str "https://" 
     (:server-name request-url) 
     ":" 
     (:server-port request-url) 
     (:uri request-url))) 

(defn require-https 
    [handler] 
    (fn [request] 
    (if (and (= (:scheme request) :http) 
      (= (get-in request [:headers "host"]) "secure.mydomain.com")) 
     (ring.util.response/redirect (https-url request)) 
     (handler request)))) 

Но когда я пытаюсь подключиться к http://secure.mydomain.com, я устанавливаю порт в адресной строке браузера https://secure.mydomain.com:80/ и получил это сообщение ERR_SSL_PROTOCOL_ERROR.

+0

Вам необходимо привязать к переменной окружения порта, обычно на Heroku. В ваших журналах есть сообщения? –

+0

Я не видел никаких проблем в своих журналах. Теперь, если я попробую '(-> route (wrap-ssl-redirect {: ssl-port (Integer/parseInt (get (System/getenv)" PORT "" 5000 "))}', я получаю желтые флажки в своих журналах с 'status = 301', и браузер отображает 5-значный порт рядом с моим доменным именем. В моей конфигурации heroku у меня нет' PORT' var. – leontalbot

+0

Можете ли вы обновить свой вопрос с помощью журналов, и точный повторяя шаги, которые вы выполняете, вместе с тем, что сработало в прошлом для вас на Heroku? –

ответ

0

Жыве lib-noir и его wrap-force-ssl Fn.

Мне просто нужно было немного изменить его в соответствии с моими потребностями (у меня есть сертификат SSL.для субдоменов, даже если мое Clojure приложение обрабатывает более одного домена)

Вот мой сноска:

(defn wrap-force-ssl 
    "Almost like in lib-noir. 
    If the request's scheme is not https [and is for 'secure.'], redirect with https. 
    Also checks the X-Forwarded-Proto header." 
    [app] 
    (fn [req] 
    (let [headers (:headers req) 
      host (headers "host")] 
     (if (or (= :https (:scheme req)) 
       (= "https" (headers "x-forwarded-proto")) 
       (not= "secure.mydomain.com" host)) ;you might not need this! 
     (app req) 
     (noir.response/redirect (str "https://" host (:uri req)) :permanent))))) 

Благодаря Криса Грейнджер и друзей!

+1

Спасибо! Это действительно полезно. Одна мысль, возможно, захочет рассмотреть возможность проверки ': query-string' в запросе и добавить ее в место перенаправления. – adamneilson

+0

@adamneilson Можете ли вы привести пример или предложить отредактировать? – leontalbot

+1

Я думал что-то вроде строк: '(noir.response/redirect (if (nil? (: Query-string req)) (формат« https: //% s% s »host (: uri req)) (формат «https: //% s% s?% S» host (: uri req) (: query-string req))): постоянный) ' – adamneilson

2

На Heroku вам нужно bind to the port, они дают вам переменную окружения. Heroku также сидит балансировки нагрузки перед вашим приложением. Они прекратят соединение SSL и свяжутся с вашим приложением через HTTP, поэтому схема, которую будет видеть ваше приложение, всегда будет HTTP. Стандарт wrap-ssl-redirect не будет работать с этим сценарием, я не думаю, что он когда-либо будет успешно перенаправлен (он будет думать, что пользователь подключается через HTTP, даже если он перенаправляется на HTTPS).

Однако Heroku добавляет x-forwarded-proto в заголовки каждого запроса, чтобы обойти это, чтобы вы могли видеть, какой протокол использует ваш клиент. В том же ring.middleware.ssl namespace является промежуточным программным обеспечением wrap-forwarded-scheme.

«Связующее ПО, которое изменяет:.. Схему отображения запроса на значение данного в заголовке запроса Это полезно, если ваше приложение сидит за обратного прокси или балансировки нагрузки, который обрабатывает SSL транспорт Заголовок по умолчанию для x-forwarded-proto. "

Если вы перенесите свои маршруты первым, а затем wrap-ssl-redirect, то он должен правильно перенаправить на HTTPS. Вы можете также добавить ring.middleware.ssl/wrap-hsts для обеспечения HSTS, а также:

(wrap-forwarded-scheme (wrap-ssl-redirect (wrap-hsts app))) 
+1

hmm .. добавление 'wrap-forwarded-scheme' делает chrome say:' ERR_TOO_MANY_REDIRECTS'. Журналы Heroku выглядят так: 'at = info method = GET path = "/ favicon.ico" host = www.mydomain.com request_id = 0e85ea4c-044c-4bf4-a16b-fe729aabad3b fwd = "77.74.193.277" dyno = web.1 connect = 0ms service = 72ms status = 301 байты = 170' – leontalbot

+1

Возможно, рассматривая возможность открытия проблемы в проекте GitHub с просьбой предоставить документацию, показывающую, как использовать ее с Heroku, они, вероятно, самые лучшие люди, которых можно задать. –

+0

Не работает. Я открыл билет, но, к сожалению, Хероку мог найти ответ. Это происходит ... – leontalbot