5
votes

I'm stuck with this for about 3 days. Basically, i'm trying to generate a JWT token in laravel using Tymon. This is my controller file.

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\User;
use JWTAuth;
use JWT;
use Tymon\JWTAuthExceptions\JWTException;
use Tymon\JWTAuth\Contracts\JWTSubject as JWTSubject;

class AuthenticateController extends Controller
{
 public function index()
{
 //   
}
 public function authenticate(Request $request)
{

    $user = User::where('email', $request->only('email'))->first(); 
    dd($user); //This does show some output      
    $token = JWTAuth::fromUser($user); //returns error message

    return ["error" => NULL, "token" => $token];

 }
}

I tested this api using Chrome postman, but it is reporting this error:

ErrorException in JWT.php line 73: Argument 1 passed to Tymon\JWTAuth\JWT::fromUser() must be an instance of Tymon\JWTAuth\Contracts\JWTSubject, instance of App\User given, called in /Users/shankerm/mccadmin/laravel/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php on line 217 and defined

Pls give me some advice. Im new to Laravel and struggling with this for a long time. Thanks.

4

4 Answers

16
votes

You are using the newer version of the package. This requires that the User Model implements this contract. Solve it by doing this in your model:

use Tymon\JWTAuth\Contracts\JWTSubject;

class User extends Model implements JWTSubject {
7
votes

Firstly you need to implement the Tymon\JWTAuth\Contracts\JWTSubject contract on your User model, which requires that you implement the two methods getJWTIdentifier() and getJWTCustomClaims().

Below is the example how your code could look. please make any changes necessary to suit your own needs.

<?php

namespace App;

use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements JWTSubject
{
    use Notifiable;

    // Rest omitted for brevity

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

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

Configure Auth guard

Note: This will only work if you are using Laravel 5.2 and above.

Inside the config/auth.php file you will need to make a few changes to configure Laravel to use the jwt guard to power your application authentication.

Make the following changes to the file:

'defaults' => [
    'guard' => 'api',
    'passwords' => 'users',
],

...

'guards' => [
    'api' => [
        'driver' => 'jwt',
        'provider' => 'users',
    ],
],

Here we are telling the api guard to use the jwt driver, and we are setting the api guard as the default.

0
votes

Two issues that could be happening according to previous experience

  1. Setting the jwt as the default auth driver. You can do it like this

    'api' => [ 'driver' => 'jwt', 'provider' => 'users', 'hash' => false, ],

    1. Not implementing the JWTSubject in your preferred Model i.e for a user model you can do it like this

    class User extends Authenticatable implements JWTSubject{ then implement the functions by the interface as below

    /** * @inheritDoc */ public function getJWTIdentifier() { return $this->getKey(); }

    /**
     * @inheritDoc
     */
    public function getJWTCustomClaims()
    {
        return [];
    }
    

it could also be you have not generated a jwt auth key

php artisan jwt:secret

with this you should have a entry like this in your .env

JWT_SECRET={value generated}
0
votes

In Addition to steps provided in JWT Documentation, please comment the following part available in config/auth.php which comes by default after installing laravel.

'users' => ['driver' => 'database', 'table' => 'users',],