11
votes

I am trying to use JWT for laravel web page instead of session. so I made some changes.

  1. Installed jwt-auth and configure

  2. Then changed default guard as api in config/auth.php

    'defaults' => [
        'guard' => 'api',
        'passwords' => 'users',
    ],
    
    'guards' => [
        ...
    
        'api' => [
            'driver' => 'token',
            'provider' => 'users',
        ],
    ],
    

Now I am getting error

(1/1) FatalErrorException Call to undefined method Illuminate\Auth\TokenGuard::attempt() in AuthenticatesUsers.php (line 75)

How to fix this and start token authentication for laravel web page(blades not API).

5
Have you used $ php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider" and also set a secret key in the config file??Hiren Gohel
I think you need to use ['middleware' => 'auth:api'] in your routes. Try this and let me know the results!Hiren Gohel
Is it works for you??Hiren Gohel
It would work after authentication, but I am getting this error while authentication via laravel default scaffolding login page submission.Niklesh Raut

5 Answers

2
votes

I'm also using jwt protecting our api. You should change your config like below:

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

'guards' => [
    ...

    'api' => [
        'driver' => 'jwt', // KEY POINT!!!
        'provider' => 'users',
    ],
],

Make sure the jwt library installed correctly:

  1. Tymon\JWTAuth\Providers\LaravelServiceProvider::class is added in your config/app.php.

  2. Your user model implements JWTSubject interface if you use eloquent model in your provider.

2
votes

I found the solution here : https://github.com/tymondesigns/jwt-auth/issues/860

In /routes/api.php - added a few basic authentication routes

Route::post('login', 'Auth\LoginController@login');

Route::get('/user', function (Request $request) {
    $user = $request->user();
    return dd($user);
})->middleware('auth:api');

In /app/http/Controller/auth/LoginController.php

and then override methods in login contoller

public function login(Request $request)
{
    $credentials = $request->only(["email","password"]);
    if ($token = $this->guard()->attempt($credentials)) {
        return $this->sendLoginResponse($request, $token);
    }

    $this->incrementLoginAttempts($request);
    return $this->sendFailedLoginResponse($request);
}

protected function sendLoginResponse(Request $request, $token)
{
    $this->clearLoginAttempts($request);

    return $this->authenticated($request, $this->guard()->user(), $token);
}

protected function authenticated(Request $request, $user, $token)
{
    setcookie("jwt_token", $token);
    return redirect('/');
    return response()->json([
        'token' => $token,
    ]);
}

protected function sendFailedLoginResponse(Request $request)
{
    return response()->json([
        'message' => "not found",
    ], 401);
}

Adding middleware AddToken

public function handle($request, Closure $next)
{
    $token = isset($_COOKIE["jwt_token"])?$_COOKIE["jwt_token"]:"";
    //$request['token'] = $token;//this is working
    $request->headers->set("Authorization", "Bearer $token");//this is working
    $response = $next($request);
    //$response->header('header name', 'header value');
    return $response;
}

Register middleware in Kernel.php

 protected $middleware = [
    ....
    \App\Http\Middleware\AddToken::class,
];
0
votes

I think you can try this :

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

'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

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

EDIT

You can find some help from the step by step example. In this example you need to focus on how to configure and use that token base authentication.

Hope this help you well.

0
votes

Please refer this link. If you are using api as default then laravel authentication will throw an error.

0
votes

Laravel uses default Session based authentication out of the box with the default scaffolding users-view-controller that you already have. You have additional means of adding your own custom guard in the doc, so you can make use of the guard as needed.

Therefore as @KevinPatel suggested, revert back to the default configuration, then in your route: group the route you want to be under JWT authentication, add the JWTMiddleware, in this case you have to update the controller responsible for your authentication to use the JWTAuth instead of the default auth.

You should check this answer if you need to understand it better check this answer on Laracasts

One recommended way to incorporate the JWTAuth is to go for Dingo API (of course you are not building api, but) because Dingo already added some flesh to the authentication and other routes management - so things are pretty easy to use and configure