今天我发现,我弄的登陆检验有些可以被跳过。
我用一个Route Middleware做检验,大概就这样:
<?php
function AreYouMga () {
$app = \Slim\Slim::getInstance();
if ( $app->getEncryptedCookie("who_are_you") !== "mga") {
$app->response()->redirect('/login', 303);
}
}
就是看看加密的Cookies里是不是“mga”,不是就跳转到登陆页面。
这是看起来能正常工作(实际有问题)的一例:
<?php
$app->get('/posts', 'AreYouMga', function() use ($app, $db) {
$posts = $db->getAllPosts();
$app->render('posts.php', array('posts' => $posts));
});
如果不是我(mga)访问 /posts
就会重定向到/login
。
下面这个就不行了:
<?php
$app->get('/reset', 'AreYouMga', function () use ($app, $db) {
$db->reset();
$app->response()->redirect('/', 303);
});
不管有没有登陆,访问/reset
都可以清空我的数据库然后重定向。就是因为这里的重定向有差别,我才发现这个问题。上面第一例的闭包里没有重定向所以看起来正常,实际上还是执行了。
难道是cookies设错了?还是说Slim的Route Middleware不能实现短路,闭包一定会被执行?不会是Bug吧?…
折腾一番之后,我看文档才发现有两个redirect()
方法,一个是Slim对象的,一个是Response对象的。 Slim对象的redirect()
设置HTTP Header然后通过抛异常实现短路,而Response对象只是设置一下HTTP Header。
所以把重定向那句换成
$app->redirect('/login', 303);
就OK了。
嗯,就样了。