SLIM 3 logn中间件进入循环
SLIM 3 logn middleware enter in a loop
我在使用 SLIM 3 登录中间件时遇到了一些问题。
在我尝试去的任何路线中,我都会收到此浏览器错误:"ERR_TOO_MANY_REDIRECTS"。
好像是SLIM进入了一个循环,无法渲染登录页面。
我能做什么?
我显然已经完成了会话变量的 print_r,当然它最初是空的,只有在正确登录后才会填充..
这是我的索引php:
<?
use Slim\Views\PhpRenderer;
session_start();
define( "BASE_URL", "/test/");
define("ROOT_PATH", $_SERVER["DOCUMENT_ROOT"] . "/test/");
require 'vendor/autoload.php';
require 'config/db.php';
require('functions/middleware.php');
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
use Illuminate\Database\Capsule\Manager as Capsule;
$capsule = new Capsule;
$capsule->addConnection([
'driver' => 'mysql',
'host' => DB_HOST,
'port' => DB_PORT,
'database' => DB_NAME,
'username' => DB_USER,
'password' => DB_PASSWORD,
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
]);
$capsule->bootEloquent();
$capsule->setAsGlobal();
$config['displayErrorDetails'] = true;
$config['addContentLengthHeader'] = false;
$config['determineRouteBeforeAppMiddleware'] = true;
$app = new \Slim\App(['settings' => $config]);
$container = $app->getContainer();
$container['renderer'] = new PhpRenderer("./templates");
$container['notFoundHandler'] = function ($container) {
return function ($request, $response) use ($container) {
return $container['renderer']->render($response, "/404.php");
};
};
// Apply the middleware to every request.
$app->add($loggedInMiddleware);
include 'routes.php';
$app->run();
这是中间件包含的文件:
<?
// Check the user is logged in when necessary.
$loggedInMiddleware = function ($request, $response, $next) {
$route = $request->getAttribute('route');
$routeName = $route->getName();
$groups = $route->getGroups();
$methods = $route->getMethods();
$arguments = $route->getArguments();
# Define routes that user does not have to be logged in with. All other routes, the user
# needs to be logged in with.
$publicRoutesArray = array(
'login',
'logout'
);
if (!$_SESSION && !in_array($routeName, $publicRoutesArray)) {
// redirect the user to the login page and do not proceed.
$response = $response->withRedirect('/test/login');
} else {
if ($routeName == "login")
return $response->withRedirect('/test/dashboard');
// Proceed as normal...
$response = $next($request, $response);
}
return $response;
};
这些是 GET 和 POST 登录路由:
$app->get('login', function ($request, $response, $args) {
return $this->renderer->render($response, "/login.php", $args);
})->setName('login');
$app->post('login', function ($request, $response, $args) {
$res = [];
if(!$_POST['username'] || !$_POST['password']) {
$res['error'] = "Inserisci i campi richiesti per il LogIn";
return $this->response->withJson($res);
}
$thisUser = \test\Model\users::select("users.*")
->where("username",$_POST['username'])
->where("password",MD5($_POST['password']))
->get();
if (!$thisUser[0]){
$res['error'] = "I dati inseriti non corrispondono a nessun utente";
return $this->response->withJson($res);
}
$_SESSION['user']['id'] = $thisUser[0]['id'];
$_SESSION['user']['username'] = $thisUser[0]['username'];
$_SESSION['user']['role'] = $thisUser[0]['role'];
$_SESSION['user']['name'] = $thisUser[0]['name'];
$_SESSION['user']['profileImg'] = "https://www.media-rdc.com/medias/32d9119760683046ad0c1e2d7e50e009/p_50x50/stsm144.jpg";
$res['success'] = true;
return $this->response->withJson($res);
});
最后这是我的 .htaccess:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]
好吧,我已经尝试了很多东西;我不确定这是否是正确的答案,但它解决了问题(至少在我这边):
我已将您的中间件修改为:
<?php
function (\Slim\Http\Request $request, \Slim\Http\Response $response, $next) {
$route = $request->getAttribute('route');
if (empty($route)) {
throw new \Slim\Exception\NotFoundException($request, $response);
}
$routeName = $route->getName();
// Define routes that user does not have to be logged in with. All other routes, the user
// needs to be logged in with.
$publicRoutesArray = array(
'login',
'logout'
);
if ( empty($_SESSION['user']) && !in_array($routeName, $publicRoutesArray)) {
// redirect the user to the login page and do not proceed.
return $response->withRedirect('/test/login');
}
// Proceed as normal...
return $next($request, $response);
}
?>
此外,您似乎必须在定义的路由中包含 test
才能工作(或在 .htaccess 中过滤掉它们)
<?php
$app->get('/test/login', function ($request, $response, $args) {
return $this->renderer->render($response, 'index.phtml', $args);
})->setName('login');
?>
真心希望对你有所帮助
你有一个会话,因为你在一开始就开始了会话:
<?
use Slim\Views\PhpRenderer;
session_start();
...
您的中间件只是检查是否存在会话,而不是您是否设置了登录用户的 user
会话变量。
if (!$_SESSION && !in_array($routeName, $publicRoutesArray)) {
// redirect the user to the login page and do not proceed.
$response = $response->withRedirect('/test/login');
} else {
if ($routeName == "login")
return $response->withRedirect('/test/dashboard');
// Proceed as normal...
$response = $next($request, $response);
}
因此,当他们点击登录路由(但未登录)时,应用程序将进入 else 语句,这会将他们重定向到仪表板(很确定这就是 "wrong",因为您希望他们留在那里提交表单登录)。当他们点击仪表板时,该路由不是 public 路由的一部分,因此它将它们重定向回登录页面。因此,循环永远持续下去。
或许改变:
if (!$_SESSION && in_array($routeName, $publicRoutesArray) === FALSE) {
// redirect the user to the login page and do not proceed.
$response = $response->withRedirect('/test/login');
} else {
到...
if (!isset($_SESSION['user'] && in_array($routeName, $publicRoutesArray) === FALSE) {
// redirect the user to the login page and do not proceed.
$response = $response->withRedirect('/test/login');
} else {
我在使用 SLIM 3 登录中间件时遇到了一些问题。 在我尝试去的任何路线中,我都会收到此浏览器错误:"ERR_TOO_MANY_REDIRECTS"。 好像是SLIM进入了一个循环,无法渲染登录页面。 我能做什么? 我显然已经完成了会话变量的 print_r,当然它最初是空的,只有在正确登录后才会填充..
这是我的索引php:
<?
use Slim\Views\PhpRenderer;
session_start();
define( "BASE_URL", "/test/");
define("ROOT_PATH", $_SERVER["DOCUMENT_ROOT"] . "/test/");
require 'vendor/autoload.php';
require 'config/db.php';
require('functions/middleware.php');
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
use Illuminate\Database\Capsule\Manager as Capsule;
$capsule = new Capsule;
$capsule->addConnection([
'driver' => 'mysql',
'host' => DB_HOST,
'port' => DB_PORT,
'database' => DB_NAME,
'username' => DB_USER,
'password' => DB_PASSWORD,
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
]);
$capsule->bootEloquent();
$capsule->setAsGlobal();
$config['displayErrorDetails'] = true;
$config['addContentLengthHeader'] = false;
$config['determineRouteBeforeAppMiddleware'] = true;
$app = new \Slim\App(['settings' => $config]);
$container = $app->getContainer();
$container['renderer'] = new PhpRenderer("./templates");
$container['notFoundHandler'] = function ($container) {
return function ($request, $response) use ($container) {
return $container['renderer']->render($response, "/404.php");
};
};
// Apply the middleware to every request.
$app->add($loggedInMiddleware);
include 'routes.php';
$app->run();
这是中间件包含的文件:
<?
// Check the user is logged in when necessary.
$loggedInMiddleware = function ($request, $response, $next) {
$route = $request->getAttribute('route');
$routeName = $route->getName();
$groups = $route->getGroups();
$methods = $route->getMethods();
$arguments = $route->getArguments();
# Define routes that user does not have to be logged in with. All other routes, the user
# needs to be logged in with.
$publicRoutesArray = array(
'login',
'logout'
);
if (!$_SESSION && !in_array($routeName, $publicRoutesArray)) {
// redirect the user to the login page and do not proceed.
$response = $response->withRedirect('/test/login');
} else {
if ($routeName == "login")
return $response->withRedirect('/test/dashboard');
// Proceed as normal...
$response = $next($request, $response);
}
return $response;
};
这些是 GET 和 POST 登录路由:
$app->get('login', function ($request, $response, $args) {
return $this->renderer->render($response, "/login.php", $args);
})->setName('login');
$app->post('login', function ($request, $response, $args) {
$res = [];
if(!$_POST['username'] || !$_POST['password']) {
$res['error'] = "Inserisci i campi richiesti per il LogIn";
return $this->response->withJson($res);
}
$thisUser = \test\Model\users::select("users.*")
->where("username",$_POST['username'])
->where("password",MD5($_POST['password']))
->get();
if (!$thisUser[0]){
$res['error'] = "I dati inseriti non corrispondono a nessun utente";
return $this->response->withJson($res);
}
$_SESSION['user']['id'] = $thisUser[0]['id'];
$_SESSION['user']['username'] = $thisUser[0]['username'];
$_SESSION['user']['role'] = $thisUser[0]['role'];
$_SESSION['user']['name'] = $thisUser[0]['name'];
$_SESSION['user']['profileImg'] = "https://www.media-rdc.com/medias/32d9119760683046ad0c1e2d7e50e009/p_50x50/stsm144.jpg";
$res['success'] = true;
return $this->response->withJson($res);
});
最后这是我的 .htaccess:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]
好吧,我已经尝试了很多东西;我不确定这是否是正确的答案,但它解决了问题(至少在我这边):
我已将您的中间件修改为:
<?php
function (\Slim\Http\Request $request, \Slim\Http\Response $response, $next) {
$route = $request->getAttribute('route');
if (empty($route)) {
throw new \Slim\Exception\NotFoundException($request, $response);
}
$routeName = $route->getName();
// Define routes that user does not have to be logged in with. All other routes, the user
// needs to be logged in with.
$publicRoutesArray = array(
'login',
'logout'
);
if ( empty($_SESSION['user']) && !in_array($routeName, $publicRoutesArray)) {
// redirect the user to the login page and do not proceed.
return $response->withRedirect('/test/login');
}
// Proceed as normal...
return $next($request, $response);
}
?>
此外,您似乎必须在定义的路由中包含 test
才能工作(或在 .htaccess 中过滤掉它们)
<?php
$app->get('/test/login', function ($request, $response, $args) {
return $this->renderer->render($response, 'index.phtml', $args);
})->setName('login');
?>
真心希望对你有所帮助
你有一个会话,因为你在一开始就开始了会话:
<?
use Slim\Views\PhpRenderer;
session_start();
...
您的中间件只是检查是否存在会话,而不是您是否设置了登录用户的 user
会话变量。
if (!$_SESSION && !in_array($routeName, $publicRoutesArray)) {
// redirect the user to the login page and do not proceed.
$response = $response->withRedirect('/test/login');
} else {
if ($routeName == "login")
return $response->withRedirect('/test/dashboard');
// Proceed as normal...
$response = $next($request, $response);
}
因此,当他们点击登录路由(但未登录)时,应用程序将进入 else 语句,这会将他们重定向到仪表板(很确定这就是 "wrong",因为您希望他们留在那里提交表单登录)。当他们点击仪表板时,该路由不是 public 路由的一部分,因此它将它们重定向回登录页面。因此,循环永远持续下去。
或许改变:
if (!$_SESSION && in_array($routeName, $publicRoutesArray) === FALSE) {
// redirect the user to the login page and do not proceed.
$response = $response->withRedirect('/test/login');
} else {
到...
if (!isset($_SESSION['user'] && in_array($routeName, $publicRoutesArray) === FALSE) {
// redirect the user to the login page and do not proceed.
$response = $response->withRedirect('/test/login');
} else {