xp-forge / web-auth

Web Authentication
0 stars 0 forks source link

Access to authentication #7

Open thekid opened 3 years ago

thekid commented 3 years ago

Currently web handlers have access to the authenticated user via the request value named user, which is returned by the authentication flow. However, the following use-cases are not possible without workarounds:

To make this possible, a new value authentication could be passed to the request containing methods to access user and session.

thekid commented 3 years ago

This is a primitive logout implementation (abbreviated example inside App::routes()):

return [
  '/logout' => function($req, $res) use($sessions) {
    if ($session= $sessions->locate($req)) {
      $session->destroy();
      $session->transmit($res); // This is necessary with the current implementation but IMO shouldn't be
    }

    $res->answer(302);
    $res->header('Location', '/?logged-out');
  },
  // ...
}

As can be seen, it needs to know that the authentication uses a session-based approach.

thekid commented 3 years ago

First ideas

Logout:

'/logout' => function($req, $res) {
  if ($req->value('authentication')->logout($req, $res)) {
    $res->answer(302);
    $res->header('Location', '/?logged-out');
  }
},

Updating user value:

'/' => function($req, $res) {
  $user= $req->value('user');

  // Fetch user from database
  $current= $this->repo->user($user['id']);
  $req->value('authentication')->update('user', $current);
},
thekid commented 3 years ago

Another idea

Instead of a web.Request class, authentication could pass a class inherited from that, web.auth.Authenticated, thus simplifying the code as follows:

'/logout' => function(Authenticated $req, Response $res) {
  if ($req->logout($res)) {
    $res->answer(302);
    $res->header('Location', '/?logged-out');
  }
},
'/refresh' => function(Authenticated $req, Response $res) {
  $req->update('user', $this->repo->user($req->user()['id']));
},

However, decorating the Request class is quite cumbersome, there's quite a bit of methods to overwrite with delegating implemnetations.

thekid commented 3 months ago

Sessions accessor

For us, this would be:

$session= $req->session(); // Returns a web.Session instance or NULL

$session->register('key', 'value');
$session->value('key');
$session->remove('key');

// Logout
$session->destroy();