Ya hemos visto cómo un usuario puede registrarse en nuestra aplicación e iniciar sesión. Ahora es el turno del cierre de sesión. Como nuestra aplicación se basa en tokens y no en cookies, esta tarea se realizará de diferente forma al que Laravel nos provee por defecto. Necesitamos hacer lo siguiente cuando un usuario pulse en Logout o Cerrar Sesion:
- Crear la ruta necesaria.
- Guardar la fecha y hora de última conexión.
- Poner el campo online a 0/false.
- Invalidar el token actual.
- Devolver mensaje de deslogado con éxito.
Primero añadimos la ruta en el archivo de rutas:
1 |
Route::get('logout', 'TokenAuthController@logout'); |
Ahora el controlador:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public function logout(Request $request) { $user = \Auth::user(); // emitimos evento de deslogado event(new \Illuminate\Auth\Events\Logout($user)); try { $token = JWTAuth::getToken(); JWTAuth::invalidate($token); return response()->success(['user' => $user]); } catch (Exception $e) { return response()->error('error_on_login_out', $e->getStatusCode()); } } |
Vamos a crear el manejador del evento disparado en la linea 6. Este evento es propio de Laravel, nosotros nos ocuparemos de actuar cuando éste se dispare.
Para ello, registramos el evento (event) y su manejador (listener) en el siguiente archivo:
1 2 3 4 5 6 7 8 9 10 11 |
. . . . class EventServiceProvider extends ServiceProvider { protected $listen = [ . . . . 'Illuminate\Auth\Events\Logout' => [ 'App\Listeners\UpdateLastLoggedAtOnLogout', ], ]; . . . . } |
Ahora generamos los archivos (en este caso, solo el listener será generado ya que el evento ya existe en carpeta vendor de Laravel y no lo vamos a modificar):
1 |
php artisan event:generate |
Abrimos y editamos:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class UpdateLastLoggedAtOnLogout { . . . . public function handle(Logout $event) { // para que no se actualice la columna "updated_at" $event->user->timestamps = false; $event->user->last_logged_at = $event->user->current_login_time; $event->user->online = 0; $event->user->save(); // Log::info("ultima conexion: {$event->user->last_logged_at}" ); } } |
Para que no haya errores, los campos que se actualizan en el listener, deben estar en la migración de la tabla «users» y en el modelo «User» tal que:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class CreateUsersTable extends Migration { public function up() { Schema::create('users', function (Blueprint $table) { . . . . $table->boolean('online')->default(false); $table->bigInteger('current_login_time')->nullable(); $table->bigInteger('last_logged_at')->nullable(); }); } . . . . } |
1 2 3 4 |
class User extends Authenticatable implements JWTSubject { protected $hidden = [ 'current_login_time', . . . ]; } |