[PROMOÇÃO] Assine com + 30% de desconto ANUAL MENSAL (últimas horas)
Alef Silva
Criador Alef Silva 03/05/2024

Estou tendo problemas em obter os dados da sessão utilizando API com Sanctum.

A minha aplicação é multi-tenancy single-database e tem a parte web e API. Tenho um listener registrado em EventServiceProvider dentro de protected $listen que utiliza Illuminate\Auth\Events\Login 

Login::class => [
SetTenantIdSession::class
]

Listener abaixo:

<?php

namespace App\Listeners;

class SetTenantIdSession
{
    public function __construct()
    {
        //
    }

    public function handle(object $event): void
    {
        if ($event->user->role != 'master') {
            session()->put([
                'user_id'   => $event->user->id,
                'tenant_id' => $event->user->tenant_id
            ]);
        }
    }
}

O grande problema disso é que ao buscar os dados da sessão com dd(session()); na parte web em qualquer tela, os dados são retornados corretamente com 'user_id' e 'tenant_id'. Porém na parte de API com Sanctum, os dados da sessão aparecem somente no método de login e quando eu tento buscar a sessão em outros métodos mesmo passando o Bearer: token que foi gerado, não vem 'user_id' e 'tenan_id' habilitado.

Isso tem a ver com a forma que o Sanctum trabalha com sessões? será que eu devo manter a lógica do listener somente para web e criar outra lógica separada para API ao inserir 'tenant_id' e 'user_id' ?

 

 

 

Manager Carlos Ferreira 03/05/2024

Olá, Alef!

Tudo bem?

 

O protocolo http não armazena estado, logo, não é possível trabalhar com sessão em uma api rest (http).

 

No caso da API, vc quer pegar o usuário autenticado, certo?

Não muda em nada, uma vez que tem o middewlare (auth:sanctum) aplicado, você pode recuperar o usuário de todoas as formas como recupera em uma autenticação web (com sessão), exemplo:

dd(auth()->user());

Carlos Ferreira
Criador Alef Silva 03/05/2024

É que no caso eu preciso setar o user_id e tenant_id em operações de gravar registros, exemplo: ao criar um pedido de compra, será necessário gravar o usuário que fez esse registro e o tenant que ele pertence automaticamente para que seja filtrado coisas somente desse usuário e não de outros tenants com o uso do Global Scope como você ensinou no curso. Para isso eu criei um observer conforme abaixo:

<?php

namespace App\Observers;

use Illuminate\Database\Eloquent\Model;

class TenantObserver
{
    public function creating(Model $model): void
    {
        if (session()->has('tenant_id')) {
            $model->setAttribute('tenant_id', session()->get('tenant_id'));
            $model->setAttribute('user_id', session()->get('user_id'));
        }
    }
}

Esse observer funciona em tudo da parte web, mas na API não funciona por conta do HTTP não armazenar estado conforme você explicou...

Ao invés de usar o helper session() devo utilizar algo como: auth()->user()->id e auth()->user()->tenant_id?  é isso?

Alef Silva
Manager Carlos Ferreira 03/05/2024

Eu tenho um projeto multi-tenancy com api.

 

Esquece a ideia de sessão, pega o usuário e seus dados através do helper auth, ou da facede Auth, api não armazena estado.

 

Se precisa de algo que não esteja no model do usuário, vc precisa passar na request

Carlos Ferreira
Sabe a Solução? Ajude a resolver!

Precisa estar logado para conseguir responder a este ticket!

Clique Aqui Para Entrar!