Auth Middleware
Hi @adhocore, I really like this phalcon-ext and try to use for my new journey with phalcon I have question about how to implement the ApiAuth Middleware on micro app I already try it, but why always return Permission denied for all my defined route.
Here are my snippets code
config.php
--------------
// The permission scopes required for a route
'scopes' => [
/'validation' => 'user',
],
index.php
-------------
<?php
use PhalconExt\Http\Middlewares;
use PhalconExt\Http\Middleware\ApiAuth;
use PhalconExt\Http\Middleware\Cache;
use PhalconExt\Http\Middleware\Cors;
use PhalconExt\Http\Middleware\Throttle;
use Phalcon\Http\Response;
use Phalcon\Mvc\Micro as MicroApplication;
use Phalcon\Mvc\Micro\Collection;
use Phalcon\Mvc\Router;
use Vinculum\Controller\MicroController;
// Micro app
$di = require __DIR__ . '/../app/bootstrap.php';
$app = new MicroApplication($di);
$app->getRouter()->setUriSource(Router::URI_SOURCE_GET_URL);
$app->mount((new Collection)
->setPrefix('/')
->setHandler(MicroController::class, true)
->get('/', 'indexAction', 'home')
->get('validation', 'validationAction')
->post('api/auth', 'authAction')
);
$app->notFound(function () {
$data = [
'code' => 404,
'status' => 'not_found',
'message' => 'Page not found',
];
$response = new Response();
return $response->setJsonContent($data)->setStatusCode(404);
});
(new Middlewares([Throttle::class, ApiAuth::class, Cors::class, Cache::class]))->wrap($app);
Thanks for using it and opening an issue. I will take a close look and get back to you soon.
have you set up full config as in example?
also can you check if tests/Http/Middleware/ApiAuthTest.php can help you with usge?
I already set up full config like yours, the /api/auth endpoint to generate tokens/refresh is working
but the uri in scopes that have to use ApiAuth is always return permission denied even there is a Bearer tokens.
One more thing, what is exactly the values for field scopes in users table?
scope is the permission or role or both.
for example if you have configured an uri '/some/uri' with 'admin' scope then access to this uri is allowed if and only if the scope value in jwt token contains 'admin'
you can set the scope value somehow for user for which you have to authenticate using jwt. here is factory implementation: https://github.com/adhocore/phalcon-ext/blob/master/src/Factory/ApiAuthenticator.php
Hello, were you able to use the middleware?
Hi @adhocore, I already try to run in with boilerplate like yours (Phalcon Micro) and everythings work well. Then I have another question, how to implement this (JWT Auth) with my current Phalcon MVC Apps that have Basic Auth, I want to switch it with your jwt-api-auth. My boss tell me to continue (change) what my colleague did. Here is the snippet, he used it as plugin:
<?php
/**
* Description of SecurityPlugin
*
* @path apps/plugins/SecurityPlugin.php
*
*/
namespace Somenamespace\Plugin;
use Phalcon\Events\Event;
use Phalcon\Mvc\Dispatcher;
class SecurityPlugin extends BasePlugin
{
public function beforeExecuteRoute(Event $event, Dispatcher $dispatcher)
{
$this->logRequest();
$username = $this->request->getServer('PHP_AUTH_USER');
$password = $this->request->getServer('PHP_AUTH_PW');
$status = true;
if (empty($username) || empty($password)) {
$this->setResponseHttpCode(self::HTTP_CODE_400);
$this->setResponseMessage('Username & Password cannot be empty.');
$status = false;
}
$user = $this->auth($username, $password);
if (!$user) {
$this->setResponseHttpCode(self::HTTP_CODE_401);
$status = false;
} else {
if (!$this->developerMode()) {
$acl = $this->acl($dispatcher, $user->getId());
if (!$acl) {
$this->setResponseHttpCode(self::HTTP_CODE_403);
$status = false;
} else {
$this->session->set('auth', $user->toArray());
$this->session->set('resource', $acl->toArray());
}
}
}
if (!$status) {
$this->generateResponse();
return false;
}
}
private function auth($username, $password)
{
$user = $this->getApiUser($username, $password);
if (!$user) {
$this->setResponseMessage('Username & Password is not valid.');
return false;
}
if ($user->getActive() == 0) {
$this->setResponseMessage('User is not active.');
return false;
}
return $user;
}
private function acl($dispatcher, $apiUserId)
{
$module = $this->router->getModuleName();
$controller = $this->router->getControllerName();
$action = $dispatcher->getParam('action_method');
$apiResources = $this->getApiResources($module, $controller, $action, $apiUserId);
if (!$apiResources) {
$this->setResponseMessage("You don't have permission to access");
return false;
}
return $apiResources;
}
private function getApiUser($username, $password)
{
$password = md5($password);
return \Somenamespace\Base\Model\ApiUser::findFirst([
"username = '$username' AND password = '$password'",
'cache' => $this->_getCacheKeyModel([
'apiUser',
$username,
$password,
]),
]);
}
private function getApiResources($module, $controller, $action, $apiUserId)
{
return \Somenamespace\Base\Model\ApiResource::findFirst([
"api_user_id = $apiUserId AND module = '$module' AND controller = '$controller' AND action = '$action'",
'cache' => $this->_getCacheKeyModel([
'apiResource',
$module,
$controller,
$action,
$apiUserId,
]),
]);
}
}
Any idea? I really appreciate....
first thing to understand is jwt auth is meant for programmable api consumers and not usual browser requests made by end user. but i think you can still find a way out with some not-so-neat hacks around. (like saving jwt into cookie after successful login, which again not a recommendation from me)
for this reason the current jwt auth support is explicitly supported for micro api auth (edit: should work for mvc as well when used as json api server) and i wanted to have another middleware for mvc in #8 but never finished that (sorry to say that not enough motivation and time for that)
Alrite, thank you very much then..... I really appreciate this package
a new version of this package has been released https://github.com/adhocore/phalcon-ext/releases/tag/v0.0.9