jwt-auth icon indicating copy to clipboard operation
jwt-auth copied to clipboard

Use with a custom (Statamic flat-file) User model (not Eloquent-based user model)

Open CedsTrash opened this issue 8 months ago • 4 comments

Summary

Hi, I'm not sure if this a feature request or a bug.

I'm trying to implement this package in a Statamic (Flat-file CMS for Laravel) project. Out of the box, Statamic users are stored in flat files (yaml) instead of a database.

I created a new user provider in my AppServiceProvider.php. The provider is exactly the same as the standar Statamic one, with a distinct name:

use Statamic\Auth\UserProvider;

class AppServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        Auth::provider('jwt_statamic', function () {
            return new UserProvider;
        });
    }
}

Then I've set my provider in auth.php with my custom User model:

'providers' => [
        'users' => [
            'driver' => 'statamic',
        ],

        'jwt_users' => [
            'driver' => 'jwt_statamic',
            'model' => App\Models\JwtFileUser::class,
        ],
],

Here is my User model:

<?php

namespace App\Models;

use PHPOpenSourceSaver\JWTAuth\Contracts\JWTSubject;
use Statamic\Auth\File\User;

class JwtFileUser extends User implements JWTSubject
{
    /**
     * Get the identifier that will be stored in the subject claim of the JWT.
     *
     * @return mixed
     */
    public function getJWTIdentifier(): mixed
    {
        return $this->getKey();
    }

    /**
     * Return a key value array, containing any custom claims to be added to the JWT.
     *
     * @return array
     */
    public function getJWTCustomClaims(): array
    {
        return [];
    }
}

But I get an error message when I reach Auth::guard('api')->attempt($request->only('email', 'password'));:

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Auth;
use Statamic\Http\Controllers\User\LoginController as BaseController;
use Statamic\Http\Requests\UserLoginRequest;

class JwtAuthController extends BaseController
{
    public function __construct()
    {
        $this->middleware('auth:api', ['except' => ['login']]);
    }

    public function login(UserLoginRequest $request)
    {
        // removed for simplicity

        $token = Auth::guard('api')->attempt($request->only('email', 'password'));

        // removed for simplicity
    }
}

The error message is the following:

TypeError: PHPOpenSourceSaver\JWTAuth\JWTGuard::login(): Argument #1 ($user) must be of type PHPOpenSourceSaver\JWTAuth\Contracts\JWTSubject, Statamic\Auth\File\User given, called in /vendor/php-open-source-saver/jwt-auth/src/JWTGuard.php on line 151 in file /vendor/php-open-source-saver/jwt-auth/src/JWTGuard.php on line 164

I'm surprised because my Model implements JWTSubject. So I'm guessing this happens because my User model doesn't extend a regular Laravel Eloquent User model?

Thanks for your help.

CedsTrash avatar Jun 07 '24 21:06 CedsTrash