Reputation: 322
I am currently trying to implement route authentication filtering in Slim 3. What I would like to do is:
$app->get("/route", Filter::$guest(), function ($request, $response, $args) {
...
});
or maybe
$app->get("/route", function ($resquest, $response, $args) {
})->add(Filter::Admin);
and the Filter class would be:
class Filter
{
public static admin()
{
// Check if user is an admin.
// If not, throw an Error
}
...
In Slim 2, I could use someting like this
Filter.php
$authenticationCheck = function ($required) use ($app) {
return function () use ($required, $app) {
if ((!$app->auth && $required) || ($app->auth && !$required)) {
$app->redirect($app->urlFor("home"));
}
};
};
$authenticated = function () use ($authenticationCheck) {
return $authenticationCheck(true);
};
$guest = function () use ($authenticationCheck) {
return $authenticationCheck(false);
};
$admin = function () use ($app) {
return function () use ($app) {
if (!$app->auth || !$app->auth->isAdmin()) {
$app->notFound();
}
};
};
and in routes I could do:
$app->get("/route", $guest(), function () use ($app) {
//Route
});
I know that I can get the route through middleware, but I can't think of a good way to diffrenciate between a "admin" route and a normal route without having to build some sort of list.
Upvotes: 1
Views: 2273
Reputation: 8738
You could create a basic middleware class Authorization
:
<?php
class Authorization
{
/**
* Authorization 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)
{
$user = ""; //It should come from some place :)
if(!$this->isAuthorized($user)){
return $response->withRedirect('/notAuthorized');
}
return $next($request, $response);
}
/**
* Check if the given user is authorized.
*
* @param string $user The user to check.
*
* @return boolean True if the user is authorized, false otherwise.
*/
protected function isAuthorized($user){
return false;
}
}
Then you can extend it and create one middleware for guest authorization and another one for admin authorization:
<?php
class GuestAuthorization extends Authorization
{
protected function isAuthorized($user){
//Are you a guest?
$isGuest = true; //Your magic business here
return $isGuest;
}
}
class AdminAuthorization extends Authorization
{
protected function isAuthorized($user){
//Are you an admin?
$isAdmin = false; //Your magic business here
return $isAdmin;
}
}
Let's try with some routes and define the notAuthorized
one:
<?php
$app->get("/guestRoute", function ($resquest, $response, $args) {
return $response->write("You're a guest");
})->add(new \GuestAuthorization());
$app->get("/adminRoute", function ($resquest, $response, $args) {
return $response->write("You're an admin");
})->add(new \AdminAuthorization());
$app->get("/notAuthorized", function ($resquest, $response, $args) {
return $response->write("You're not authorized for this, my son!");
});
PROs:
CONs:
Upvotes: 1