使用Play Framework在Heroku上重定向和登录cookie

时间:2012-01-23 21:47:26

标签: https heroku playframework session-cookies

我玩了!框架Heroku项目有三个部署。一个用于运行我的开发机器,一个用于Heroku上的beta,另一个用于Heroku上的生产。他们的http和https网址如下:

             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上有效?

1 个答案:

答案 0 :(得分: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