Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,993 changes: 1,993 additions & 0 deletions docs/plans/2026-06-28-0709-jwt-hypervel-native-parity-refactor.md

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions src/auth/src/AuthManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public function createSessionDriver(string $name, array $config): SessionGuard
$guard = new SessionGuard(
$name,
$this->createUserProvider($config['provider'] ?? null),
$this->app['session.store'],
$this->app->make('session.store'),
$this->app,
rehashOnLogin: $repository->boolean('hashing.rehash_on_login', true),
timeboxDuration: $repository->integer('auth.timebox_duration', 200000),
Expand All @@ -122,9 +122,9 @@ public function createSessionDriver(string $name, array $config): SessionGuard
// When using the remember me functionality of the authentication services we
// will need to be set the encryption instance of the guard, which allows
// secure, encrypted cookie values to get generated for those cookies.
$guard->setCookieJar($this->app['cookie']);
$guard->setCookieJar($this->app->make('cookie'));

$guard->setDispatcher($this->app['events']);
$guard->setDispatcher($this->app->make('events'));

if (isset($config['remember'])) {
$guard->setRememberDuration($config['remember']);
Expand Down
11 changes: 8 additions & 3 deletions src/auth/src/AuthServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,17 @@ protected function registerRequestUserResolver(): void
protected function registerEventRebindHandler(): void
{
$this->app->rebinding('events', function ($app, $dispatcher) {
if (! $app->resolved('auth')
|| $app['auth']->hasResolvedGuards() === false) {
if (! $app->resolved('auth')) {
return;
}

foreach ($app['auth']->getGuards() as $guard) {
$auth = $app->make('auth');

if ($auth->hasResolvedGuards() === false) {
return;
}

foreach ($auth->getGuards() as $guard) {
if (method_exists($guard, 'setDispatcher')) {
$guard->setDispatcher($dispatcher);
}
Expand Down
3 changes: 3 additions & 0 deletions src/auth/src/GuardHelpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ public function getProvider(): ?UserProvider

/**
* Set the user provider used by the guard.
*
* Boot or tests only. The provider is stored on the worker-lifetime guard
* and affects every subsequent request.
*/
public function setProvider(UserProvider $provider): void
{
Expand Down
12 changes: 12 additions & 0 deletions src/auth/src/SessionGuard.php
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,9 @@ protected function rehashUserPasswordForDeviceLogout(#[SensitiveParameter] strin

/**
* Register an authentication attempt event listener.
*
* Boot-only. Listener registrations persist on the worker-lifetime dispatcher
* and affect every subsequent request.
*/
public function attempting(callable $callback): void
{
Expand Down Expand Up @@ -775,6 +778,9 @@ protected function getRememberDuration(): int

/**
* Set the number of minutes the remember me cookie should be valid for.
*
* Boot-only. The duration is stored on the worker-lifetime guard and affects
* every subsequent request.
*/
public function setRememberDuration(int $minutes): static
{
Expand All @@ -799,6 +805,9 @@ public function getCookieJar(): CookieJar

/**
* Set the cookie creator instance used by the guard.
*
* Boot or tests only. The cookie jar is stored on the worker-lifetime guard
* and affects every subsequent request.
*/
public function setCookieJar(CookieJar $cookie): void
{
Expand All @@ -815,6 +824,9 @@ public function getDispatcher(): ?Dispatcher

/**
* Set the event dispatcher instance.
*
* Boot or tests only. The dispatcher is stored on the worker-lifetime guard
* and affects every subsequent request.
*/
public function setDispatcher(Dispatcher $events): void
{
Expand Down
25 changes: 17 additions & 8 deletions src/boost/docs/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ As discussed in this documentation, you can interact with these authentication s
<a name="hypervels-api-authentication-services"></a>
#### Hypervel's API Authentication Services

Hypervel provides two optional packages to assist you in managing API tokens and authenticating requests made with API tokens: [Passport](/docs/{{version}}/passport) and [Sanctum](/docs/{{version}}/sanctum). Please note that these libraries and Hypervel's built-in cookie based authentication libraries are not mutually exclusive. These libraries primarily focus on API token authentication while the built-in authentication services focus on cookie based browser authentication. Many applications will use both Hypervel's built-in cookie based authentication services and one of Hypervel's API authentication packages.
Hypervel provides optional packages to assist you in managing API tokens and authenticating requests made with API tokens, including [Sanctum](/docs/{{version}}/sanctum) and [JWT authentication](/docs/{{version}}/jwt). Please note that these libraries and Hypervel's built-in cookie based authentication libraries are not mutually exclusive. These libraries primarily focus on API token authentication while the built-in authentication services focus on cookie based browser authentication. Many applications will use both Hypervel's built-in cookie based authentication services and one of Hypervel's API authentication packages.

**Passport**

Expand All @@ -95,16 +95,22 @@ In response to the complexity of OAuth2 and developer confusion, we set out to b

Hypervel Sanctum is a hybrid web / API authentication package that can manage your application's entire authentication process. This is possible because when Sanctum based applications receive a request, Sanctum will first determine if the request includes a session cookie that references an authenticated session. Sanctum accomplishes this by calling Hypervel's built-in authentication services which we discussed earlier. If the request is not being authenticated via a session cookie, Sanctum will inspect the request for an API token. If an API token is present, Sanctum will authenticate the request using that token. To learn more about this process, please consult Sanctum's ["how it works"](/docs/{{version}}/sanctum#how-it-works) documentation.

**JWT Authentication**

[Hypervel JWT](/docs/{{version}}/jwt) provides stateless bearer token authentication using signed JSON Web Tokens. JWT authentication is useful when your application needs signed tokens for API, mobile, or service-to-service requests and does not need Sanctum's database-backed personal access tokens or OAuth2 grant flows.

<a name="summary-choosing-your-stack"></a>
#### Summary and Choosing Your Stack

In summary, if your application will be accessed using a browser and you are building a monolithic Hypervel application, your application will use Hypervel's built-in authentication services.

Next, if your application offers an API that will be consumed by third parties, you will choose between [Passport](/docs/{{version}}/passport) or [Sanctum](/docs/{{version}}/sanctum) to provide API token authentication for your application. In general, Sanctum should be preferred when possible since it is a simple, complete solution for API authentication, SPA authentication, and mobile authentication, including support for "scopes" or "abilities".
Next, if your application offers an API that will be consumed by third parties, you will choose between [Sanctum](/docs/{{version}}/sanctum), [JWT authentication](/docs/{{version}}/jwt), or an OAuth2 server to provide API token authentication for your application. In general, Sanctum should be preferred when possible since it is a simple, complete solution for API authentication, SPA authentication, and mobile authentication, including support for "scopes" or "abilities".

If you are building a single-page application (SPA) that will be powered by a Hypervel backend, you should use [Hypervel Sanctum](/docs/{{version}}/sanctum). When using Sanctum, you will need to [manually implement your own backend authentication routes](#authenticating-users) or use another headless authentication backend service that provides routes and controllers for features such as registration, password reset, email verification, and more.

If you are building a single-page application (SPA) that will be powered by a Hypervel backend, you should use [Hypervel Sanctum](/docs/{{version}}/sanctum). When using Sanctum, you will either need to [manually implement your own backend authentication routes](#authenticating-users) or utilize [Hypervel Fortify](/docs/{{version}}/fortify) as a headless authentication backend service that provides routes and controllers for features such as registration, password reset, email verification, and more.
An OAuth2 server may be chosen when your application absolutely needs all of the features provided by the OAuth2 specification.

Passport may be chosen when your application absolutely needs all of the features provided by the OAuth2 specification.
JWT authentication may be chosen when your application wants stateless signed bearer tokens without storing each issued token in the database.

And, if you would like to get started quickly, we are pleased to recommend [our application starter kits](/docs/{{version}}/starter-kits) as a quick way to start a new Hypervel application that already uses our preferred authentication stack of Hypervel's built-in authentication services.

Expand Down Expand Up @@ -746,12 +752,15 @@ Route::post('/settings', function () {

You may define your own authentication guards using the `extend` method on the `Auth` facade. You should place your call to the `extend` method within a [service provider](/docs/{{version}}/providers). Since Hypervel already ships with an `AppServiceProvider`, we can place the code in that provider:

> [!NOTE]
> If you want to authenticate requests using JSON Web Tokens, use Hypervel's [JWT authentication](/docs/{{version}}/jwt) package. This section is for custom authentication systems that are not already provided by Hypervel.

```php
<?php

namespace App\Providers;

use App\Services\Auth\JwtGuard;
use App\Services\Auth\TokenGuard;
use Hypervel\Contracts\Foundation\Application;
use Hypervel\Support\Facades\Auth;
use Hypervel\Support\ServiceProvider;
Expand All @@ -765,10 +774,10 @@ class AppServiceProvider extends ServiceProvider
*/
public function boot(): void
{
Auth::extend('jwt', function (Application $app, string $name, array $config) {
Auth::extend('token', function (Application $app, string $name, array $config) {
// Return an instance of Hypervel\Contracts\Auth\Guard...

return new JwtGuard(Auth::createUserProvider($config['provider']));
return new TokenGuard(Auth::createUserProvider($config['provider']));
});
}
}
Expand All @@ -779,7 +788,7 @@ As you can see in the example above, the callback passed to the `extend` method
```php
'guards' => [
'api' => [
'driver' => 'jwt',
'driver' => 'token',
'provider' => 'users',
],
],
Expand Down
1 change: 1 addition & 0 deletions src/boost/docs/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
- [Task Scheduling](/docs/{{version}}/scheduling)
- ## Security
- [Authentication](/docs/{{version}}/authentication)
- [JWT Authentication](/docs/{{version}}/jwt)
- [Authorization](/docs/{{version}}/authorization)
- [Permission](/docs/{{version}}/permission)
- [Email Verification](/docs/{{version}}/verification)
Expand Down
Loading