We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

What is the best way to design an authentication using RESTful concepts?

Hello Guys,

Firstly, i want say that i am migrating from CI to Phalcon, and until now this framework is showing very, very good!

Well, my doubt is about designing a RESTful.

Until now i had no problem defening the routes, controllers and everything. (Except that i`m getting a very big index.php with all those routes).

What is the best way to make a authentication in Phalcon ? A lot of articles say that is using Tokens, but how in Phalcon? Maybe sessions?

Thanks



98.9k

hi, tokens is the best option because it's a good practice avoid stateless data (sessions) in RESTful APIs

Nice, thanks Phalcon, how could i achieve this in Phalcon/Micro ?



98.9k
Accepted
answer

You can add a middleware that implements authorization before every request to your API: https://docs.phalcon.io/en/latest/reference/micro.html#middleware-events

Nice, i accomplished this using the ("beforeExecuteRoute").



6.1k

Oauth2 and HMAC are the 2 main ways. I already designed a phalcon hmac restful api (https://github.com/jeteokeeffe/php-hmac-rest-api). To read more about about HMAC, i recommend this link, https://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/

HMAC is the way to go. I implemented it with an events manager, on 'beforeExecuteRoute'. All of this using micro app, which is really the best way for serving RESTful API interface.



2.5k
edited Jun '16

You can add a middleware that implements authorization before every request to your API: https://docs.phalcon.io/en/latest/reference/micro.html#middleware-events

It finally works. But because I search a lot after that, i add here more details

use Phalcon\Loader; use Phalcon\Mvc\Micro; use Phalcon\DI\FactoryDefault; use Phalcon\Db\Adapter\Pdo\Mysql as PdoMysql; use Phalcon\Http\Response; use Phalcon\Events\Manager as EventsManager; use Phalcon\Session\Adapter\Files as Session;

try{ // you need to start the session // Start the session the first time when some component request the session service

$di->setShared('session', function () { $session = new Session(); $session->start(); return $session; }); And to make an authentication

// Create a events manager

$eventsManager = new EventsManager();

// Listen all the application events

$eventsManager->attach('micro', function ($event, $app) {

if ($event->getType() == 'beforeExecuteRoute') {
    if ($app->session->get('auth') == false) {
    try{
        $connexion = $app->request->getJsonRawBody();

            // Get the data from the user

            $nomUsager    = $connexion->nomUsager;
            $motDePasse = $connexion->motDePasse;

            // Find the user in the database - depends on your table

            $utilisateur = membre::findFirst(
            array(
                "NomUsager = :nomUsager: AND MotDePasseMembre = :motDePasse:",
                'bind' => array(
                    'nomUsager'    => $nomUsager,
                    'motDePasse' => md5($motDePasse) //simplier

                )
               )
        );

            if ($utilisateur != false) {

              $app->session->set(
             'auth',
              array(
                  'id'   => $utilisateur->id,
                 'NomMembre' => $utilisateur->NomMembre,
          'PrenomMembre' => $utilisateur->PrenomMembre
                  )
           );

              $app->flash->success('Bienvenue ' . $utilisateur->PrenomMembre);
       return true;

           }else{
            $app->flash->error('Mauvais usager/mot de passe');
        return false;
       }
         }
         catch (Exception $e) {
     //Create a response
edited Jun '16

Well, after a couple of Micro APIs, I found it most convenient to implement autorization inside before Micro event.

//HMAC digest check
$app->before(function () use ($app) {
    // Executed before every route is executed
//Before executing the handler. It can be used to control the access to the application
}
edited Sep '16

Ok, I do exactly this way checking for token, decode and valid date. But, how I report to the Controller class the user's request from the decoded token? Any tips?

edited Sep '16

You don't need to report anything to the controllers. This before Micro app bound event does all the job. The thing is, if your auth check failed, you only need to return false from before() closure, and execution flow will stop w/o calling any handler (Controller). Controllers are then called only after before() (middleware) events finished with success.

That's simple and efficient implementation of validating access to the application.