ZF2并强制特定路由的HTTPS

Daw*_*wid 3 https routes zend-framework2

我正在尝试在访问/ account route下的任何页面时实现强制https.我发现这个问题ZF2与https一起使用,它可以...部分工作.我的路线:

'router' => array(
    'routes' => array(
        'account' => array(
            'type' => 'Scheme',
            'options' => array(
                'route' => '/account',
                'scheme' => 'https',
                'defaults' => array(
                    'controller' => 'Account\Controller\Account',
                    'action' => 'index',
                ),
            ),
            'may_terminate' => true,
            'child_routes' => array(
                'default' => array(
                    'type' => 'Literal',
                    'options' => array(
                        'route' => '/',
                        'defaults' => array(
                            'controller' => 'Account\Controller\Account',
                            'action' => 'index',
                        ),
                    ),
                ),
                'signin' => array(
                    'type' => 'Segment',
                    'options' => array(
                        'route' => '/signin[/:type]',
                        'defaults' => array(
                            'controller' => 'Account\Controller\Account',
                            'action' => 'signin',
                        ),
                        'constraints' => array(
                            'type' => '[a-zA-Z][a-zA-Z0-9-_]*',
                        ),
                    ),
                ),
                'signout' => array(
                    'type' => 'Segment',
                    'options' => array(
                        'route' => '/signout',
                        'defaults' => array(
                            'controller' => 'Account\Controller\Account',
                            'action' => 'signout',
                        ),
                    ),
                ),
                'register' => array(
                    'type' => 'Segment',
                    'options' => array(
                        'route' => '/register[/:step]',
                        'defaults' => array(
                            'controller' => 'Account\Controller\Account',
                            'action' => 'register',
                        ),
                        'constraints' => array(
                            'step' => '[a-zA-Z][a-zA-Z0-9-_]*',
                        ),
                    ),
                ),
            ),
        ),
    ),
),
Run Code Online (Sandbox Code Playgroud)

来自Skeleton Application的应用程序模块的主页路由(从github克隆).每当我访问/ account的任何子路径时,它都会抛出404:

http(s)://domain.my/account/signin = 404, wrong
http(s)://domain.my/account/* = 404, wron
https://domain.my/signin = signin page, wrong should be /account/signin
http://domain.my/ = ok, main page
http://domain.my/account = 404, wrong
https://domain.my/ = wrong, account page should be main page
Run Code Online (Sandbox Code Playgroud)

通常我的问题是:页面应该通过http或https BUT /帐户访问,并且子路由只能通过https访问.

编辑

好的,我已经尝试了chained_routes,但这不是我想要实现的.我想做这样的事情:

用户未登录:类型:http: //domain.my/account - >重定向到 https://domain.my/account/login (我知道我可以实现此目的$authService->hasIdentity())然后重定向到 https://domain.my /帐户

类型: http ://domain.my/account/login - >重定向到 https://domain.my/account/login

类型:http: //domain.my/account/edit - >重定向到 https://domain.my/account/login 然后转到https://domain.my/account/edit

与登录用户相同,当他从/ account路径访问任何内容时,它会被重定向到相同的URL但使用https.

Jur*_*man 5

如果要重定向用户,则无法通过路由执行此操作.简单地说,您必须首先接受路由匹配,然后检查所使用的方案是否为https,如果不是,则重定向.这将是控制器逻辑.因此,请忽略用例中的方案路由,并在控制器中检查https.

在Zend Framework 1中,我们有一个自定义帮助程序Https,如果方案是http,您可以使用它来强制将页面重定向到https:

public function init ()
{
    $this->https->forceHttps(array('index', 'login', 'edit'));
}

public function indexAction ()
{
    // code here
}

public function loginAction ()
{
    // code here
}

public function editAction ()
{
    // code here
}
Run Code Online (Sandbox Code Playgroud)

如果您在http上点击索引,登录或编辑,您将被重定向到https.如果您使用https,则没有重定向.

目前我们没有Zend Framework 2的插件,但我认为这是你必须寻找的解决方案.使该功能成为控制器插件,因此您可以在不同的控制器之间重用它.Zend Framework 2的一个例子可能更像是这样的:

use Zend\Http\Response;

public function loginAction()
{
    // If return value is response, this means the user will be redirected
    $result = $this->forceHttps();
    if ($result instanceof Response) {
        return $result;
    }

    // code here
}
Run Code Online (Sandbox Code Playgroud)

控制器插件可能如下所示:

use Zend\Uri\Http as HttpUri;

class ForceHttps extends AbstractPlugin
{
    public function __invoke()
    {
        $request = $this->getController()->getRequest();

        if ('https' === $request->getUri()->getScheme()) {
            return;
        }

        // Not secure, create full url
        $plugin = $this->getController()->url();
        $url    = $plugin->fromRoute(null, array(), array(
            'force_canonical' => true,
        ), true);

        $url    = new HttpUri($url);
        $url->setScheme('https');

        return $this->getController()->redirect()->toUrl($url);
    }
}
Run Code Online (Sandbox Code Playgroud)

注意我没有对此进行测试,因此代码中可能存在一些错误.但你应该通过这个例子得到这个想法.

  • 我和原始海报有同样的问题,我发现实际上,通过https://bitbucket.org/netglue/zf2-require-ssl-module,我能够使它像原来的海报一样工作,在路线上组态.一旦你通过composer添加该模块,你可以在你的路由默认值中加入'force-ssl'=>'ssl',它就像魅力一样:) (2认同)