← Security

SECURITY FEATURE

Session Auth

Google is the only login path; once signed in, the demo can switch roles to show how permissions change.

Feature Guide

A quick orientation block that answers the essential questions: what this feature does, how it works, why it matters, and the key concepts behind it.

What this does

Google signs the user in, then the session stores the selected demo role and re-hydrates it on every request.

Session State

Google sign-in required

Sign in with Google first. The role selector is only available after authentication.

Sign in with Google required

Authorization is required to access role switching in this demo.

Google OAuth #[SessionSegment] AuthResult #[AsAuthHandler]

Verified against Semitexa Ultimate 2026.09.19.1020

Session Auth

Authenticate once per session — the framework stores identity and re-hydrates it on every request.

How it works

Google OAuth is the single login path. After the callback completes, the authenticated identity is written into a typed Session Payload. On every subsequent request the auth handler reads that payload back out and reconstructs the principal, so handlers never touch raw session keys.

Why this matters

Session auth in long-running PHP workers is fragile when state leaks across requests. Semitexa isolates session read/write into the execution-scoped tier so each request gets a clean view, and the typed segment guarantees the shape is always valid.

© Harold Abelson: "Programs must be written for people to read, and only incidentally for machines to execute."

Google Auth Segment Implementation slice
<?phpdeclare(strict_types=1);namespace Semitexa\Demo\Application\Payload\Session;use Semitexa\Core\Session\Attribute\SessionSegment;#[SessionSegment('demo_google_auth')]final class GoogleAuthSessionSegment{    private ?string $state = null;    private ?string $returnTo = null;    private ?string $demoRole = null;    private ?string $lastError = null;    private ?GoogleSessionIdentityPayload $identity = null;    public function getState(): ?string    {        return $this->state;    }    public function setState(?string $state): void    {        $this->state = $state !== null && trim($state) !== '' ? trim($state) : null;    }    public function getReturnTo(): ?string    {        return $this->returnTo;    }    public function setReturnTo(?string $returnTo): void    {        $this->returnTo = $returnTo !== null && trim($returnTo) !== '' ? trim($returnTo) : null;    }    public function getDemoRole(): ?string    {        return $this->demoRole;    }    public function setDemoRole(?string $demoRole): void    {        $demoRole = $demoRole !== null ? trim($demoRole) : null;        $this->demoRole = $demoRole !== null && $demoRole !== '' ? $demoRole : null;    }    public function getLastError(): ?string    {        return $this->lastError;    }    public function setLastError(?string $lastError): void    {        $lastError = $lastError !== null ? trim($lastError) : null;        $this->lastError = $lastError !== null && $lastError !== '' ? $lastError : null;    }    public function clearLastError(): void    {        $this->lastError = null;    }    public function getIdentity(): ?GoogleSessionIdentityPayload    {        return $this->identity;    }    /**     * @param array<string, mixed>|GoogleSessionIdentityPayload|null $identity     */    public function setIdentity(array|GoogleSessionIdentityPayload|null $identity): void    {        if ($identity === null) {            $this->identity = null;        } elseif ($identity instanceof GoogleSessionIdentityPayload) {            $this->identity = $identity;        } else {            $this->identity = GoogleSessionIdentityPayload::fromArray($identity);        }    }    public function isAuthenticated(): bool    {        return $this->identity !== null            && $this->identity->getSubjectId() !== ''            && $this->identity->getEmail() !== '';    }    public function clear(): void    {        $this->state = null;        $this->returnTo = null;        $this->demoRole = null;        $this->lastError = null;        $this->identity = null;    }}

Support Semitexa
Built for developers who prefer control over magic. Your support helps keep it fast, open, and evolving.

Donate via PayPal