我有戏!具有三个部署的 Heroku 框架项目。一台用于运行我的开发机器,一台用于 Heroku 上的测试版,一台用于 Heroku 上的生产环境。它们的 http 和 https url 如下:
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 也能工作。
我的所有页面都被保护为仅限成员(member),并要求用户使用 @With(Secure.class)
注释登录。我认为这一定与登录发生在 secure.domain.com
而不是 www.domain.com
的事实有关,并且它们以某种方式生成不同的 cookies 。
有没有办法更改在 secure.domain.com
创建的登录 Cookie,使其在 www.domain.com
上工作?
最佳答案
查看有关默认 cookie 域设置的文档。
http://www.playframework.org/documentation/1.2.4/configuration#application.defaultCookieDomain
它解释了如何设置 cookie 以在所有子域中工作。
application.defaultCookieDomain
Enables session/cookie sharing between subdomains. For example, to make cookies valid for all domains ending with ‘.example.com’, e.g. foo.example.com and bar.example.com:
application.defaultCookieDomain=.example.com
关于使用 Play Framework 在 Heroku 上进行 https 重定向和登录 cookie,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8979073/