如何在 Slim v3 中实现 Slim v2 钩子作为中间件
How to implement a Slim v2 hook as middleware in Slim v3
在 Slim Framework v2 中,我使用简单的身份验证功能作为钩子来检查路由是否需要登录。
这是验证码:
$authenticate = function ( $app ) {
return function () use ( $app ) {
if ( !isset( $_SESSION['userid'] ) ) {
$_SESSION['urlRedirect'] = $app->request()->getPathInfo();
$app->flash('danger', 'You need to login');
$app->redirect('/login');
}
};
};
这是我在 Slim v2 中的使用方式:
$app->get("/user/change-password", $authenticate($app), function () use ( $app ) {
$userStuff->changePassowrd($_SESSION['userid'], $newPassword, $oldPassword);
});
我可以毫无问题地将它实现到 Slim v3,但我似乎无法理解我应该如何使用中间件来做到这一点(学习和使用功能)
我试过了:这是我的中间件 class;
<?php
namespace entity;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
class Auth
{
/**
* Example middleware invokable class
*
* @param \Psr\Http\Message\ServerRequestInterface $request PSR7 request
* @param \Psr\Http\Message\ResponseInterface $response PSR7 response
* @param callable $next Next middleware
*
* @return \Psr\Http\Message\ResponseInterface
*/
public function __invoke($request, $response, $next)
{
if ($this->authenticate()) {
$response = $next($request, $response);
} else {
echo 'You need to login';
}
return $response;
}
public function authenticate() {
if ( !isset( $_SESSION['userid'] ) ) {
return true;
}
return false;
}
}
?>
已注册:
$app->add( new entity\Auth() );
而且我不知道如何像在 Slim v2 中那样在路由上使用它,我应该在路由中的什么地方添加它以检查该路由是否需要身份验证?
谢谢。
接下来是基本示例
<?php
require 'vendor/autoload.php';
session_start();
class Auth {
public function __invoke($request, $response, $next) {
if ($this->authenticate()) {
$response = $next($request, $response);
} else {
echo 'You need to login';
}
return $response;
}
public function authenticate() {
if (isset($_SESSION['userid'])) {
return true;
}
return false;
}
}
$app = new \Slim\App();
$app->get('/open', function($request, $response, $args){
echo 'HAPPINESS FOR EVERYBODY, FREE, AND LET NO ONE BE LEFT BEHIND!';
});
$app->get('/closed', function($request, $response, $args){
echo 'You are authenticated!';
})->add(new Auth());
$app->get('/login', function($request, $response, $args){
$_SESSION['userid'] = 1;
});
$app->run();
我认为 as authenticate
函数中存在错误,因为 !isset
意味着没有 $_SESSION['userid']
并且可能用户未登录,而您的函数告诉他已登录。
但无论如何,您可以使用 add()
方法将中间件添加到单个路由或一组路由。
你要找的实际上是排除了 Auth
中间件的路由。
您确实希望检查所有其他路线但不检查changePassword
。
在您的 __invoke
中,您需要 get the current route 并且仅在路线不是 changePassword
时才执行 authenticate
(如果那是您路线的名称)。
public function __invoke($request, $response, $next)
{
$route = $request->getAttribute('route');
if (in_array($route->getName(), ['changePassword']) || $this->authenticate()) {
$response = $next($request, $response);
} else {
echo 'You need to login';
}
return $response;
}
在 Slim Framework v2 中,我使用简单的身份验证功能作为钩子来检查路由是否需要登录。
这是验证码:
$authenticate = function ( $app ) {
return function () use ( $app ) {
if ( !isset( $_SESSION['userid'] ) ) {
$_SESSION['urlRedirect'] = $app->request()->getPathInfo();
$app->flash('danger', 'You need to login');
$app->redirect('/login');
}
};
};
这是我在 Slim v2 中的使用方式:
$app->get("/user/change-password", $authenticate($app), function () use ( $app ) {
$userStuff->changePassowrd($_SESSION['userid'], $newPassword, $oldPassword);
});
我可以毫无问题地将它实现到 Slim v3,但我似乎无法理解我应该如何使用中间件来做到这一点(学习和使用功能)
我试过了:这是我的中间件 class;
<?php
namespace entity;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
class Auth
{
/**
* Example middleware invokable class
*
* @param \Psr\Http\Message\ServerRequestInterface $request PSR7 request
* @param \Psr\Http\Message\ResponseInterface $response PSR7 response
* @param callable $next Next middleware
*
* @return \Psr\Http\Message\ResponseInterface
*/
public function __invoke($request, $response, $next)
{
if ($this->authenticate()) {
$response = $next($request, $response);
} else {
echo 'You need to login';
}
return $response;
}
public function authenticate() {
if ( !isset( $_SESSION['userid'] ) ) {
return true;
}
return false;
}
}
?>
已注册:
$app->add( new entity\Auth() );
而且我不知道如何像在 Slim v2 中那样在路由上使用它,我应该在路由中的什么地方添加它以检查该路由是否需要身份验证?
谢谢。
接下来是基本示例
<?php
require 'vendor/autoload.php';
session_start();
class Auth {
public function __invoke($request, $response, $next) {
if ($this->authenticate()) {
$response = $next($request, $response);
} else {
echo 'You need to login';
}
return $response;
}
public function authenticate() {
if (isset($_SESSION['userid'])) {
return true;
}
return false;
}
}
$app = new \Slim\App();
$app->get('/open', function($request, $response, $args){
echo 'HAPPINESS FOR EVERYBODY, FREE, AND LET NO ONE BE LEFT BEHIND!';
});
$app->get('/closed', function($request, $response, $args){
echo 'You are authenticated!';
})->add(new Auth());
$app->get('/login', function($request, $response, $args){
$_SESSION['userid'] = 1;
});
$app->run();
我认为 as authenticate
函数中存在错误,因为 !isset
意味着没有 $_SESSION['userid']
并且可能用户未登录,而您的函数告诉他已登录。
但无论如何,您可以使用 add()
方法将中间件添加到单个路由或一组路由。
你要找的实际上是排除了 Auth
中间件的路由。
您确实希望检查所有其他路线但不检查changePassword
。
在您的 __invoke
中,您需要 get the current route 并且仅在路线不是 changePassword
时才执行 authenticate
(如果那是您路线的名称)。
public function __invoke($request, $response, $next)
{
$route = $request->getAttribute('route');
if (in_array($route->getName(), ['changePassword']) || $this->authenticate()) {
$response = $next($request, $response);
} else {
echo 'You need to login';
}
return $response;
}