Authentication strategies for AssegaiPHP and standalone PHP applications.

Maintainers

Package info

github.com/assegaiphp/auth

pkg:composer/assegaiphp/auth

Statistics

Installs: 16

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

0.6.5 2026-03-26 16:48 UTC

This package is auto-updated.

Last update: 2026-04-03 03:20:19 UTC


README

Assegai Logo

Latest release Tests PHP 8.3+ License Status active

Authentication strategies for AssegaiPHP and standalone PHP applications.

Overview

assegaiphp/auth is a small authentication package built around focused strategies instead of a full auth framework.

Today the package ships with:

  • SessionAuthStrategy for session-backed login state
  • JwtAuthStrategy for stateless JWT authentication
  • OAuth2AuthStrategy for OAuth 2.0 authorization-code login flows
  • GitHubOAuthProvider as the first ready-to-use OAuth provider adapter

The package is intentionally narrow. It helps you:

  • authenticate a known user object
  • issue session or JWT auth state
  • begin and complete OAuth 2.0 login flows
  • hand a resolved OAuth user into session or JWT auth

It does not currently provide:

  • user lookup or persistence
  • registration or password reset flows
  • refresh token rotation
  • OAuth route/controllers for you
  • OAuth guard wiring
  • multiple polished provider adapters beyond GitHub

You still own the application flow around it: loading users, choosing when to authenticate, defining routes, and deciding what to do after login succeeds.

Installation

composer require assegaiphp/auth

Session Authentication

Use SessionAuthStrategy when you want the authenticated user stored in $_SESSION.

<?php

use Assegai\Auth\Strategies\SessionAuthStrategy;

$user = (object) [
  'id' => 7,
  'email' => 'user@example.com',
  'password' => password_hash('secret', PASSWORD_DEFAULT),
  'name' => 'Test User',
];

$strategy = new SessionAuthStrategy([
  'user' => $user,
  'session_name' => 'blog_api',
  'session_lifetime' => '+1 hour',
]);

if ($strategy->authenticate([
  'email' => 'user@example.com',
  'password' => 'secret',
])) {
  $currentUser = $strategy->getUser();
}

Session behavior

On successful authentication the strategy:

  • starts a session if needed
  • clones the configured user object
  • removes the password field from that clone
  • stores the sanitized user in $_SESSION['user']

Trusted session handoff

This is useful after an OAuth callback, when the user has already been verified by the provider and you just want to establish a local session.

$strategy->establishAuthenticatedUser((object) [
  'id' => 42,
  'email' => 'oauth@example.com',
  'name' => 'OAuth User',
]);

JWT Authentication

Use JwtAuthStrategy when you want to issue a JWT and later validate it from a bearer token or from a token you pass into the strategy config.

<?php

use Assegai\Auth\Strategies\JwtAuthStrategy;

$user = (object) [
  'id' => 7,
  'email' => 'user@example.com',
  'password' => password_hash('secret', PASSWORD_DEFAULT),
  'roles' => ['author'],
  'name' => 'Test User',
];

$strategy = new JwtAuthStrategy([
  'user' => $user,
  'secret_key' => 'replace-with-a-long-random-secret-key',
  'issuer' => 'blog-api',
  'audience' => 'blog-api-clients',
  'token_lifetime' => '+1 hour',
]);

if ($strategy->authenticate([
  'email' => 'user@example.com',
  'password' => 'secret',
])) {
  $token = $strategy->getToken();
}

JWT behavior

On successful authentication the strategy creates a token payload with:

  • sub
  • the configured username field
  • iat
  • exp
  • optional iss
  • optional aud
  • optional roles
  • optional name

isAuthenticated() validates either:

  • the token generated by the strategy, or
  • the Authorization: Bearer ... header when one is present

Trusted JWT handoff

This is useful after an OAuth callback when you want to mint a local API token for a provider-authenticated user.

$token = $strategy->issueTokenForUser((object) [
  'id' => 42,
  'email' => 'oauth@example.com',
  'name' => 'OAuth User',
  'roles' => ['member'],
]);

OAuth 2.0

Use OAuth2AuthStrategy when you need an authorization-code flow such as "Sign in with GitHub".

Unlike the session and JWT strategies, OAuth is a redirect-based flow, so it does not implement AuthStrategyInterface.

The OAuth flow is split into two steps:

  1. build the authorization request and redirect the user
  2. handle the callback and establish local auth state

GitHub example

<?php

use Assegai\Auth\OAuth\OAuth2AuthStrategy;
use Assegai\Auth\OAuth\Providers\GitHubOAuthProvider;
use Assegai\Auth\OAuth\State\SessionOAuthStateStore;
use Assegai\Auth\Strategies\SessionAuthStrategy;

$sessionStrategy = new SessionAuthStrategy([
  'user' => (object) [],
  'session_name' => 'blog_api',
]);

$oauth = new OAuth2AuthStrategy(
  provider: new GitHubOAuthProvider(),
  config: GitHubOAuthProvider::defaultConfig(
    clientId: 'your-github-client-id',
    clientSecret: 'your-github-client-secret',
    redirectUri: 'https://example.com/auth/github/callback',
  ),
  stateStore: new SessionOAuthStateStore(),
  sessionStrategy: $sessionStrategy,
);

$request = $oauth->beginLogin();

header('Location: ' . $request->url);
exit;

Handling the callback

<?php

use Assegai\Auth\OAuth\OAuth2AuthStrategy;
use Assegai\Auth\OAuth\Providers\GitHubOAuthProvider;
use Assegai\Auth\OAuth\State\SessionOAuthStateStore;
use Assegai\Auth\Strategies\JwtAuthStrategy;
use Assegai\Auth\Strategies\SessionAuthStrategy;

$sessionStrategy = new SessionAuthStrategy([
  'user' => (object) [],
]);

$jwtStrategy = new JwtAuthStrategy([
  'secret_key' => 'replace-with-a-long-random-secret-key',
  'user' => (object) [
    'email' => 'placeholder@example.com',
    'password' => password_hash('placeholder', PASSWORD_DEFAULT),
  ],
]);

$oauth = new OAuth2AuthStrategy(
  provider: new GitHubOAuthProvider(),
  config: GitHubOAuthProvider::defaultConfig(
    clientId: 'your-github-client-id',
    clientSecret: 'your-github-client-secret',
    redirectUri: 'https://example.com/auth/github/callback',
  ),
  stateStore: new SessionOAuthStateStore(),
  sessionStrategy: $sessionStrategy,
  jwtStrategy: $jwtStrategy,
);

$result = $oauth->handleCallback($_GET);

// $result->user
// $result->profile
// $result->sessionEstablished
// $result->jwtToken

What OAuth2AuthStrategy does

OAuth2AuthStrategy:

  • generates a secure state value
  • generates PKCE verifier/challenge by default
  • stores the state in the configured OAuthStateStoreInterface
  • exchanges the callback code for tokens
  • fetches the provider profile
  • resolves a local user object
  • optionally hands that user into session and/or JWT auth

Current OAuth boundaries

What is ready today:

  • generic OAuth provider interface
  • PKCE-enabled authorization code flow
  • session-backed state store
  • GitHub provider adapter
  • local session/JWT handoff

What you still provide:

  • the login route
  • the callback route
  • any persistence or lookup logic for provider users
  • redirects or API responses after login

Custom OAuth providers

If GitHub is not the right provider, implement OAuthProviderInterface.

You need to provide:

  • a provider name
  • how to build the authorization URL
  • how to exchange a code for tokens
  • how to fetch the provider user profile

You can also extend AbstractOAuthProvider to reuse the common HTTP and URL-building helpers.

Using the strategy interface

If the built-in session or JWT strategies are not the right fit, implement AuthStrategyInterface.

<?php

use Assegai\Auth\Interfaces\AuthStrategyInterface;

class CustomAuthStrategy implements AuthStrategyInterface
{
  public function authenticate(array $credentials): bool
  {
    return false;
  }

  public function isAuthenticated(): bool
  {
    return false;
  }

  public function getUser(): ?object
  {
    return null;
  }

  public function logout(): void
  {
  }
}

Pairing with Assegai Core

In an Assegai app, a common pattern is:

  1. load a user from your repository or service
  2. pass that user into a session or JWT strategy, or complete an OAuth callback
  3. establish local auth state
  4. read authentication state from your guards, providers, or handlers

This package handles the strategy side of that flow. The application still owns the surrounding request flow.

API surface

AuthStrategyInterface

Method Description
authenticate(array $credentials): bool Validates credentials and establishes authentication state.
isAuthenticated(): bool Checks whether the current strategy considers the request authenticated.
getUser(): ?object Returns the authenticated user or token-backed user payload.
logout(): void Clears the current authentication state.

SessionAuthStrategy

Method Description
establishAuthenticatedUser(object $user): void Establishes trusted session auth without re-checking credentials.

JwtAuthStrategy

Method Description
getToken(): string Returns the last generated JWT.
getDecoded(): \stdClass Decodes the current JWT with the configured key and algorithm.
issueTokenForUser(object $user): string Issues a JWT for a trusted user object without re-checking credentials.

OAuth2AuthStrategy

Method Description
beginLogin(): OAuthAuthorizationRequest Builds the provider redirect request and persists state/PKCE data.
handleCallback(array $callback): OAuthLoginResult Validates the callback, resolves the provider user, and optionally establishes local auth state.

Running tests

vendor/bin/pest

License

MIT. See LICENSE.