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

标签 https heroku playframework session-cookies

我有戏!具有三个部署的 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/

相关文章:

scala - 在 Play 中的模板调用中调用函数作为参数

asp.net-mvc - 计划将 https 用于 MVC 网站(使用域/子域)——最佳实践?

java - 我可以通过 Heroku 使用 DynamoDB 吗?

ruby-on-rails - 图标未显示在 heroku 中,但它们在本地

git - 如何在 Heroku 上使用 1 个共享模块部署单独的 2 个应用程序

scala - 操作后重定向到上一页的模式

ruby - Sinatra + HTTPS 重定向到 HTTP?

security - Java gRPC - TLS - 如何在客户端设置双向 TLS?

ssl - 是否有可能获得 ip :port instead of a domain name? 的 ssl 证书

playframework - 如何在页面模板和主模板之间传递非字符串参数?