【问题标题】:Best way to force SSL for certain controllers?为某些控制器强制使用 SSL 的最佳方法?
【发布时间】:2012-10-29 02:32:00
【问题描述】:

我想对某些控制器强制使用 SSL,并为其他所有控制器删除 SSL。前段时间我在自定义 Controller 类的 _init() 中有一个 sn-p,它没有像我希望的那样工作:

$ssl = $this->request->is('ssl');

$forceSecured = in_array($this->request->controller, array('Orders', 'Customers'));

//remove SSL for non-ssl pages
if ($ssl && !$forceSecured) {
    return $this->redirect(Router::match(
                    $this->request->params,
                    $this->request,
                    array('absolute' => true, 'scheme' => 'http://')
            )
    );
}

// Force ssl on for ssl pages
if (!$ssl && $forceSecured) {
    return $this->redirect(Router::match(
                    $this->request->params,
                    $this->request,
                    array('absolute' => true, 'scheme' => 'https://')
            )
    );
}

我支持旧版应用程序,因此我定义了多个硬编码路由。我确信我可以在 Router::connect 中使用处理程序,但我宁愿检查所有请求。延续路线会是去这里的路吗?

【问题讨论】:

    标签: php lithium


    【解决方案1】:

    两件事:(1) 你不能从_init() 返回一个Response 对象(这是redirect() 返回的),以及(2) 你有一个微妙的设计问题。我建议这样做:

    protected $_secure = false;
    
    public function __invoke($request, $params, array $options = array()) {
        if (!$this->_secure && !$request->is('ssl')) {
            return parent::__invoke($request, $params, $options);
        }
        return $this->redirect(Router::match($request->url, $request, [
            'absolute' => true, 'scheme' => 'https://'
        ]));
    }
    

    观察:

    • 您正在重定向到相同的 URL,但对于协议,冗余生成 URL 没有意义
    • 特定控制器是否被重定向的决定由控制器决定;当您达到这一点(并且您可能达到这一点)不仅仅是每个控制器,而是每个动作时,这一点变得更加重要

    【讨论】:

    • 返回Response 对象是我遇到麻烦的地方。另外,我想我没有足够抽象它。旁注,$this->redirect line 缺少右括号。
    【解决方案2】:

    为什么让它进入应用程序?如果您正在使用特定路由来强制使用 ssl,请使用 htaccess 重写。

    Ssl 是一个传输协议细节,与您的站点代码无关,让 apache(或 nginx)处理这些细节。分工负责处理事情的最佳方式。

    如果您提供要捕获的精确网址,我相信 somone 可以帮助重写条件逻辑

    【讨论】:

    • 我有点同意这一点,但考虑一下链接生成和反向路由。应用程序输出重定向或 http 链接然后必须由 Web 服务器再次重定向是低效的。
    • @rmarscher 当应用程序发出 30 倍重定向时,它仍然是另一个请求往返。我说完全切断应用程序并让它由 apache 完成,在应用程序看到它之前不要介意路由它。
    • 不同意。是否保护页面的决定是一项业务决策。 (1) 重写规则不提供能够用业务术语表达的抽象,并且 (2) 您已经有了业务逻辑的位置:控制器;为什么要分开?您所说的优化级别很少是一个有效的问题。
    • 通常我会同意@Ray,但 Nate Abele 是对的。就我而言,这是一个商业决策,应该存在于代码中。此外,在代码中部署比 apache 或 nginx 配置更容易。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-10
    • 1970-01-01
    • 2011-02-15
    • 1970-01-01
    • 1970-01-01
    • 2015-07-14
    相关资源
    最近更新 更多