Jwt-auth: Proper installation instructions for Laravel 5.7

Created on 15 Oct 2018  路  26Comments  路  Source: tymondesigns/jwt-auth

Proper installation instructions for Laravel 5.7

Really, need a proper walk-through of installation

Your environment

| Q | A
| ----------------- | ---
| Bug? | no / yes
| New Feature? | no / yes
| Framework | Laravel
| Framework version | 5.7
| Package version | 1.0.0-rc.3
| PHP version | 7.1

Steps to reproduce

Had to follow 3 different bug reports to get things working.

Expected behaviour

I should be able to follow one single version of the truth for the combination I am installing it for.

Actual behaviour

Had to fiddle around with things for 2 hours to get them to work... 馃憥

Most helpful comment

Hey @vsecades,

can you share these steps that you have to do in order to get all working?

I'm upgrading a project to Laravel 5.7, and are having a lot of problems.

All 26 comments

Hey @vsecades,

can you share these steps that you have to do in order to get all working?

I'm upgrading a project to Laravel 5.7, and are having a lot of problems.

hy @vsecades
please share your step,,

it is working as expected. The docs is also working properly which step did you failed?

This comment should help solve the issue for most I think.

The docs also needs updating. I had to delve into the issues to find out how to at least install (following the docs resulted in jwt:secret throwing an error)

I believe the only step missing is composer update. I was getting

There are no commands defined in the "jwt" namespace.

Until I updated my composer.

I've installed 1.0.0-rc.3 and was able to install correctly BUT the login() function in the AuthController example in the docs derives the token from Auth()->attempt() which return a boolean.

Should the User model be extending a different class, all I see is an interface with two abstracts to implement.

@82rules it returns boolean which is correct. You check using that boolean and generate token

@shirshak55 I dont see in the docs how to generate the token. I'm following the instructions provided https://jwt-auth.readthedocs.io/en/develop/quick-start/

The way I got it working was to resolve JWTAuth in the auth controller and substitute it for auth()

`use Illuminate\Http\Request;
use Tymon\JWTAuth\JWTAuth;
use App\Http\Controllers\Controller;

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

/**

  • Get a JWT via given credentials.
    *
  • @return \Illuminate\Http\JsonResponse
    */
    public function login()
    {
    $credentials = request(['email', 'password']);
if (! $token = $this->auth->attempt($credentials)) {
  return response()->json(['error' => 'Unauthorized'], 401);
}

return $this->respondWithToken($token);

}`

Let me know if there is a proper method for generating the token.

Can you format the code .

Here is my config which works properly

namespace YOURNAMESPACEHERE
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Auth;

class AuthController extends Controller
{
    /**
     * Create a new AuthController instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth:api', ['except' => ['login']]);
    }

    /**
     * Get a JWT token via given credentials.
     *
     * @param  \Illuminate\Http\Request  $request
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function login(Request $request)
    {
        $credentials = $request->only('email', 'password');

        if ($token = $this->guard()->attempt($credentials)) {
            return $this->respondWithToken($token);
        }

        return response()->json(['error' => 'Invalid Login Details'], 401);
    }

    /**
     * Get the authenticated User.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function me()
    {
        return response()->json($this->guard()->user(), 200);
    }

    /**
     * Log the user out (Invalidate the token).
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function logout()
    {
        $this->guard()->logout();

        return response()->json(['message' => 'Successfully logged out']);
    }

    /**
     * Refresh a token.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function refresh()
    {
        return $this->respondWithToken($this->guard()->refresh());
    }

    /**
     * Get the token array structure.
     *
     * @param  string $token
     *
     * @return \Illuminate\Http\JsonResponse
     */
    protected function respondWithToken($token)
    {
        return response()->json([
            'access_token' => $token,
            'token_type'   => 'bearer',
            'expires_in'   => $this->guard()->factory()->getTTL() * 60,
        ]);
    }

    /**
     * Get the guard to be used during authentication.
     *
     * @return \Illuminate\Contracts\Auth\Guard
     */
    public function guard()
    {
        return Auth::guard('api');
    }
}

@82rules - today I struggled with making this run as well.
I think key part of the docs is:

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

Which makes default auth guard to be 'api'. If you do not do that, you need to change the call in login() from

    /**
     * Get a JWT via given credentials.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function login()
    {
        $credentials = request(['email', 'password']);

        if (! $token = auth()->attempt($credentials)) {
            return response()->json(['error' => 'Unauthorized'], 401);
        }

        return $this->respondWithToken($token);
    }

to

    public function login(): JsonResponse
    {
        $credentials = request(['email', 'password']);
        if (!$token = auth('api')->attempt($credentials)) {
            return response()->json(['error' => 'Unauthorized'], 401);
        }
        return $this->respondWithToken($token);
    }

Note the auth() helper is called with argument 'api'

i try to follow instruction in wiki, then i get error
"Call to undefined method Illuminate\\Auth\\TokenGuard::attempt()",.

then i refactor my controller with @jamby77, still get error.

but when i use laravel 5.6, its no problem :thinking:
anyone who success using jwt auth in laravel 5.7 can share the setup :pray:

@muhtarudinsiregar see above my reply it is working perfectly on laravel 5.7.

Did you configured config/auth.php file too? Many people arenot configuring that.

@shirshak55 yeah, already configured config/auth.php. you can check my auth.php here https://gist.github.com/muhtarudinsiregar/2444f502c173f292073348be732687c5

@muhtarudinsiregar use this it is working fine for me

namespace YOURNAMESPACEHERE
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Auth;

class AuthController extends Controller
{
    /**
     * Create a new AuthController instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth:api', ['except' => ['login']]);
    }

    /**
     * Get a JWT token via given credentials.
     *
     * @param  \Illuminate\Http\Request  $request
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function login(Request $request)
    {
        $credentials = $request->only('email', 'password');

        if ($token = $this->guard()->attempt($credentials)) {
            return $this->respondWithToken($token);
        }

        return response()->json(['error' => 'Invalid Login Details'], 401);
    }

    /**
     * Get the authenticated User.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function me()
    {
        return response()->json($this->guard()->user(), 200);
    }

    /**
     * Log the user out (Invalidate the token).
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function logout()
    {
        $this->guard()->logout();

        return response()->json(['message' => 'Successfully logged out']);
    }

    /**
     * Refresh a token.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function refresh()
    {
        return $this->respondWithToken($this->guard()->refresh());
    }

    /**
     * Get the token array structure.
     *
     * @param  string $token
     *
     * @return \Illuminate\Http\JsonResponse
     */
    protected function respondWithToken($token)
    {
        return response()->json([
            'access_token' => $token,
            'token_type'   => 'bearer',
            'expires_in'   => $this->guard()->factory()->getTTL() * 60,
        ]);
    }

    /**
     * Get the guard to be used during authentication.
     *
     * @return \Illuminate\Contracts\Auth\Guard
     */
    public function guard()
    {
        return Auth::guard('api');
    }
}

@shirshak55 i solved my problem about
"Call to undefined method Illuminate\\Auth\\TokenGuard::attempt()",
and your code work too, thank you :+1:

Its because i forget set my middleware with jwt-auth in routes but in documentation no one mention it. I dont know if its dingo/api middleware or jwt-auth. You can follow this tutorial its work with laravel 5.7.

hmm it is in docs
https://jwt-auth.readthedocs.io/en/develop/quick-start/

where did you check?

@shirshak55 i check in jwt-auth wiki here but no one mention that jwt-auth in middleware. if you check readthedoc part Add some basic authentication routes, in routes used 'middleware' => 'api' not jwt.auth.

api will work because in config/auth.php api array you will set jwt :)

i mean this

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

I am currently using laravel 5.7 development branch which is latest and jwt is working really fine with api auth.

I wrote this hope it helps https://medium.com/@hdcompany123/laravel-5-7-and-json-web-tokens-tymon-jwt-auth-d5af05c0659a

thank you @shirshak55, my bad, i forget to change api driver to jwt :+1:

@shirshak55 I followed your guide...

JWTAuth::attempt($payload); works fine.

\Auth::guard('api')->attempt($payload); always returns false. :-/

https://medium.com/@hdcompany123/laravel-5-7-and-json-web-tokens-tymon-jwt-auth-d5af05c0659a

This works well, once you realize everything is being done on the .env file. Anyhow, closing as it is resolved, the package mantainer SHOULD update instructions. Not going to kill them.

First Run php artisan package:discover
Then php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"
Then php artisan jwt:secret

you should use auth('api')->attempt()

I've installed 1.0.0-rc.3 and was able to install correctly BUT the login() function in the AuthController example in the docs derives the token from Auth()->attempt() which return a boolean.

Should the User model be extending a different class, all I see is an interface with two abstracts to implement.

This comment should help solve the issue for most I think.

The docs also needs updating. I had to delve into the issues to find out how to at least install (following the docs resulted in jwt:secret throwing an error)

me too

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mihailo-misic picture mihailo-misic  路  3Comments

phamduong picture phamduong  路  3Comments

lbottoni picture lbottoni  路  3Comments

hfalucas picture hfalucas  路  3Comments

marciomansur picture marciomansur  路  3Comments