强制规范使用HTTPS协议

15

我希望我的客户部分使用https,例如注册、登录、个人详情和订单详情等。我已经设置了我的路由以包括https协议(我可以通过https访问客户部分),但我无法强制我的链接使用https:

<a class="register" href="<?php echo $this->url('customer/default', array('controller' => 'registration', 'action' => 'index'), array('scheme' => 'https', 'force_canonical' => true,)); ?>">Register</a>

我得到的是:http://myproject.dev/customer/registration

我想要的是:https://myproject.dev/customer/registration

它似乎使用了当前的方案 - 所以如果我在http上,那么url就是http,如果我在https上,那么url就是https。

如何强制$this-> url始终使用https方案?

'router' => array(
  'routes' => array(
    'customer' => array(
      'type' => 'Zend\Mvc\Router\Http\Literal',
      'options' => array(
        'route' => '/customer',
        'scheme' => 'https',
        'defaults' => array(
          '__NAMESPACE__' => 'Customer\Controller',
          'https' => true,
          'controller' => 'Index',
          'action' => 'index',
        ),
      ),
      'child_routes' => array(
        'default' => array(
          'type' => 'Segment',
          'options' => array(
            'route' => '/[:controller[/:action]]',
            'scheme' => 'https',
            'constraints' => array(
              'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
              'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
            ),
            'defaults' => array(
            ),
          ),
        ),
      ),
    ),
  ),
),

[编辑]

myproject.dev 是我的本地计算机,我已更改了主机和虚拟主机文件,并设置了虚拟主机文件以接受 SSL,但这不是问题所在。

我已将路由类型更改为 Zend\Mvc\Router\Http\Scheme 并添加了方案选项,但生成的网址如下:https://myproject.dev:80/registration,这会生成一个 SSL 连接错误,因为它试图连接到端口 80!

当我将 child_routestype 更改为 scheme 时,生成的网址为:https://myproject.dev:80/customer

[编辑]

作为临时解决方案,如果用户尝试通过非安全方案访问客户部分,我正在进行 htaccess 重定向:

RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} ^/customer/?.*$
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

我不喜欢这种方法,因为它不应该是必要的!

[编辑]

虽然我想让我的客户部分使用https,但我不希望网站的其余部分使用。


你有两个选择:1)使用Apache重定向,或2)使用PHP重定向。但我首先想问为什么您只想让网站的一部分使用HTTPS。将整个网站设为安全模式对用户更友好。 - Andrea
4个回答

5

使用Zend\Uri\UriFactory;

在您的操作顶部添加以下代码,或者在插件中创建一个方法。

$uri = $this->getRequest()->getUri();
        $uri = (string) $uri;
        $url = UriFactory::factory($uri);
        $http = 'http';
        $http_current = $url->getScheme();
        if($http == $http_current){
            $url->setScheme('https');
            return $this->redirect()->toUrl($url);
        }

4

请在您的 .htaccess 文件中添加以下两行内容。

<IfModule mod_rewrite.c>
      RewriteEngine on
      RewriteCond %{HTTP_HOST} !^myproject\.
      RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
</IfModule>

它将运行在https协议上。


我不想在整个网站上运行https,只想在客户部分上运行。目前,我正在执行类似于上面的重写规则,但仍然认为这应该在应用程序逻辑中处理。 - Richard Parnaby-King

3
我认为,所有以/customer开头的URL应该在HTTP守护进程层面上进行自动重定向。所有流行的HTTP服务器(如Apache、Nginx或Lighttpd)都允许此类配置。在我看来,让业务逻辑关注网络安全是不好的做法。

2

使用 ServerUrl 和 URL 视图助手的组合来构造您的 URL,例如:

<?php
$this->getHelper('ServerUrl')->setScheme('https')
?>
<a href="<?php echo $this->serverUrl($this->url('customer/default', array('controller' => 'registration', 'action' => 'index'), array('force_canonical' => true,))); ?>">Link Caption</a>

这将强制链接是完全限定的,而不是相对的,并且将强制方案为https,而不会导致端口指定错误。

我已经尝试过了,但是出现了一个异常,提示助手无法加载ServerUrl。我需要将其作为依赖项包含吗?作为视图助手,我认为不需要... - Richard Parnaby-King

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接