Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Kinde Auth Php Laravel Package

kinde-oss/kinde-auth-php

kinde-oss/kinde-auth-php is the official Kinde SDK for PHP, making it easy to add secure authentication to PHP apps. It supports OAuth/OIDC login, registration, logout, social and passwordless sign-in, and token handling with minimal setup.

Deep Wiki
Context7

Getting Started

  • Install with composer require kinde-oss/kinde-auth-php. There is no Laravel service provider to discover, no migrations, and no published Blade views—this is a framework-agnostic OIDC/OAuth2 client, so expect to write the Laravel glue yourself.
  • Read the README in this order: the authorization-URL example, the callback/token-exchange example, then the client class source. Those three tell you what the SDK actually owns versus what you must own (state, session storage, user provisioning, middleware).
  • Configure through config/services.php and .env, never env() calls in code: KINDE_DOMAIN/issuer, KINDE_CLIENT_ID, KINDE_CLIENT_SECRET, KINDE_REDIRECT_URI, KINDE_POST_LOGOUT_REDIRECT_URI, and scopes (openid profile email offline_access). Use route('kinde.callback') for the redirect URI so every environment produces its own exact URL.
  • In the Kinde dashboard, register the callback and logout URLs before writing code. Mismatched redirect URIs are the most common first-day failure and the SDK cannot fix them.
  • Minimal wiring: three routes—GET /auth/redirect, GET /auth/callback, POST /auth/logout—handled by one controller. Redirect builds the Kinde auth URL with state (and PKCE if supported), stores state in the session, and redirects. Callback validates state, exchanges the code for tokens, validates the ID token, then calls Auth::login() on a local user keyed by the sub claim.
  • First use case: replace Breeze/Jetstream's password login with "Sign in with Kinde" for an internal app. Keep a local users table with kinde_id (the sub), email, name, and a JSON column for roles/org claims. Protect the app with Laravel's standard auth middleware; you do not need a custom guard for a normal session-based web app.
  • Fastest proof: a throwaway route that redirects to Kinde and dd()s the callback claims. Once you see sub, email, aud, iss, exp, and any org/role claims, refactor into a service class and controller.

Implementation Patterns

  • Wrap the SDK in a KindeService bound as a singleton in a service provider. Controllers and middleware should call your service, not SDK classes directly. This keeps SDK types out of your domain, gives you one place to add logging/retries, and makes tests trivial.
  • Use Laravel's session guard rather than a custom guard for web apps. After the callback, resolve or create the user and call Auth::login($user, remember: true). A custom UserProvider only pays off if you need stateless bearer-token auth for APIs.
  • Put the flow in a dedicated KindeAuthController with redirect, callback, and logout actions. Name the routes and derive the redirect URI from them; do not hardcode hosts in config.
  • Provision users with updateOrCreate(['kinde_id' => $claims['sub']], [...]). Treat sub as the only stable identity. Store org code, roles, and permissions as claims on login, and refresh them on each login rather than only at registration.
  • Map Kinde roles/permissions to Laravel gates and policies in an AuthServiceProvider or a small mapper class. Avoid scattering if ($user->role === 'admin') checks; define Gate::define('manage-billing', ...) once and use @can/authorize() everywhere.
  • For APIs, add a separate middleware that reads the Authorization: Bearer header, validates the access token against Kinde's JWKS (signature, iss, aud, exp, nbf), resolves the local user from sub, and sets the request user. Do not reuse the web session middleware for token auth, and do not accept ID tokens as API credentials.
  • Token lifecycle: store access/refresh/ID tokens server-side in the session (or an encrypted cookie) for web. Refresh proactively before expiry, and persist the rotated refresh token—Kinde rotates refresh tokens, so the old one becomes unusable. Serialize refresh with a lock so concurrent requests don't invalidate each other.
  • Logout is two steps: Auth::logout(), $request->session()->invalidate(), regenerateToken(), then redirect to Kinde's end-session endpoint with id_token_hint and post_logout_redirect_uri. Clearing only the Laravel session leaves the Kinde SSO session alive and the user gets silently signed back in.
  • Multi-tenancy: pass org_code on the authorization URL, persist the selected org in session, and scope every query by tenant. For an org switcher, re-run the auth redirect with the new org_code rather than mutating local state only.
  • Webhooks: subscribe to Kinde user/org events and handle them in queued jobs. Verify the webhook signature, make handlers idempotent by event ID, and use webhooks to deactivate users who were removed in Kinde.
  • Testing: bind a fake KindeService in the container for feature tests, and test the callback with a locally signed test token or a mocked token exchange. Assert that invalid state and expired codes redirect to a friendly error page rather than a 500.
  • Use the SDK's HTTP client extension point (typically a PSR-18/Guzzle client) to add retry and correlation-ID middleware for token and userinfo calls.

Gotchas and Tips

  • This is not a Laravel package. There is no guard, middleware, migration, or UI. Budget real time for the OAuth glue, and compare against Socialite with a generic OIDC provider or a Laravel-specific Kinde integration if you want batteries included.
  • Low adoption (roughly two dozen stars) means a small community and few battle-tested answers. Pin the version, read the source for the auth URL and token exchange, and keep your wrapper thin enough to replace. Check whether the README's last release actually aligns with the code you install.
  • Confirm in the source whether state and PKCE are generated and validated by the SDK or left to you. If left to you, store state in the session (or Redis in a load-balanced setup), reject mismatches, and use PKCE even for confidential clients.
  • Redirect URI matching is exact: scheme, host, port, path, trailing slash, and www all matter. APP_URL misconfiguration and php artisan config:cache baking stale values are the usual culprits. Run config:clear after changing Kinde settings, and never call env() outside config files.
  • Validate tokens properly: fetch JWKS, verify the signature and kid, check iss, aud, exp, and nbf with a small clock skew, and refetch JWKS when an unknown kid appears. Decoding a JWT without verification is not authentication.
  • Do not key users by email. Email and display name change; sub does not. Do not auto-link an existing local account by email unless the claim is verified and you understand the account-takeover risk.
  • Cookies: use Secure, HttpOnly, and SameSite=Lax. The callback is a top-level GET redirect, so Lax works; SameSite=Strict can drop the state cookie. Behind a proxy or load balancer, configure TrustProxies or Laravel will generate http:// redirect URIs.
  • Refresh-token rotation is a real trap. Two parallel requests refreshing at once can burn the token and log the user out. Use Cache::lock() around refresh, or refresh in one middleware and let other requests wait.
  • Missing openid breaks the ID token; missing offline_access means no refresh token. Request scopes explicitly and keep them minimal.
  • Handle the unhappy paths deliberately: user cancels at Kinde, expired authorization code, invalid state, Kinde outage, and clock skew. Redirect to a friendly error page and log correlation IDs—never log full tokens, codes, or client secrets.
  • Do not put access or refresh tokens in localStorage or expose the client secret to a browser. For SPAs and mobile, use Authorization Code + PKCE through a backend-for-frontend or the native SDK, not this server SDK with a secret.
  • Under Laravel Octane, singleton services that hold per-request user or token state will leak between requests. Keep the SDK client stateless, and resolve user context per request.
  • Debugging order: log the generated authorization URL (redact secrets), the callback query string, the token endpoint HTTP status, and the claim keys—not the token values. Cross-check against Kinde's dashboard logs, which show failed callback and logout redirects that your app never sees.
  • Useful extension points: bind your own HTTP client, decorate the service to cache JWKS and claims, and hook Laravel's Login/Logout events for audit logging and user provisioning rather than stuffing that logic into the controller.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin