2012-01-23 77 views
2

我有一個Play!框架Heroku項目有三個部署。一個用於運行我的開發機器,一個用於測試Heroku,另一個用於Heroku的製作。他們的HTTP和HTTPS的網址如下:Https在Heroku上使用Play Framework重定向和登錄Cookie

   DEV      BETA         PRODUCTION  
HTTP URL | http://localhost:9000 http://domain-beta.herokuapps.com http://www.domain.com 
HTTPS URL | https://localhost:9443 https://domain-beta.herokuapps.com https://secure.domain.com 
HTTPS Type | My cert     Piggyback (using Heroku's cert)  Hostname-based SSL (using my cert) 

我也有一類HttpsRequired具有用於需要HTTPS方法,以及重新導向到HTTP(感謝this post的幫助)。

public class HttpsRequired extends Controller { 
    /** Called before every request to ensure that HTTPS is used. */ 
    @Before 
    public static void redirectToHttps() { 
     //if it's not secure, but Heroku has already done the SSL processing then it might actually be secure after all 
     if (!request.secure && request.headers.get("x-forwarded-proto") != null) { 
      request.secure = request.headers.get("x-forwarded-proto").values.contains("https"); 
     } 

     //redirect if it's not secure 
     if (!request.secure) { 
      String url = redirectHostHttps() + request.url; 
      System.out.println("Redirecting to secure: " + url); 
      redirect(url); 
     } 
    } 

    /** Renames the host to be https://, handles both Heroku and local testing. */ 
    @Util 
    public static String redirectHostHttps() { 
     if (Play.id.equals("dev")) { 
      String[] pieces = request.host.split(":"); 
      String httpsPort = (String) Play.configuration.get("https.port"); 
      return "https://" + pieces[0] + ":" + httpsPort; 
     } else { 
      if (request.host.endsWith("domain.com")) { 
       return "https://secure.domain.com"; 
      } else { 
       return "https://" + request.host; 
      } 
     } 
    } 

    /** Renames the host to be https://, handles both Heroku and local testing. */ 
    @Util 
    public static String redirectHostNotHttps() { 
     if (Play.id.equals("dev")) { 
      String[] pieces = request.host.split(":"); 
      String httpPort = (String) Play.configuration.get("http.port"); 
      return "http://" + pieces[0] + ":" + httpPort; 
     } else { 
      if (request.host.endsWith("domain.com")) { 
       return "http://www.domain.com"; 
      } else { 
       return "http://" + request.host; 
      } 
     } 
    } 
} 

我修改Secure.login()調用HttpsRequired.redirectToHttps()在運行前,確保所有的密碼提交加密。然後,在我的Security.onAuthenticated()中,我重定向到標準HTTP上的主頁。

這對我的開發和測試版部署很有效,但在生產中,我的所有HTTP請求都重定向到HTTPS登錄頁面。我仍然可以在HTTPS中使用整個站點,但我希望常規HTTP也可以使用。

我的所有頁面都受到會員限制,並要求用戶使用@With(Secure.class)註釋進行登錄。我認爲它必須與登錄發生在secure.domain.com而不是www.domain.com這一事實有關,並且它們以某種方式生成不同的cookie。

有沒有辦法改變在secure.domain.com創建的登錄cookie,使其工作在www.domain.com

回答

3

查看有關默認cookie域設置的文檔。

http://www.playframework.org/documentation/1.2.4/configuration#application.defaultCookieDomain

它解釋瞭如何設置cookie所有子域的工作。

application.defaultCookieDomain

啓用子域之間的會話/ cookie的共享。例如,對於 ,Cookie將對所有以「.example.com」結尾的域名有效,例如 foo.example.com和bar.example.com:

application.defaultCookieDomain=.example.com

+0

嗯。這解決了我登錄cookie的問題,但現在我遇到了一個新的問題,validation.keep()沒有通過Heroku上的HTTPS工作。提出了一個新問題[這裏](http://stackoverflow.com/questions/9166129/play-framework-on-heroku-validation-keep-isnt-working-over-https)。 –