1

I am quite new in laravel/lumen framework. I am using lumen 5.2 to build a restful API. For authentication, I am trying to implement JWT authentication I am following this https://laravelista.com/json-web-token-authentication-for-lumen article for guidance. I install and configure this https://github.com/tymondesigns/jwt-auth packages. It works fine and gives me following error if i do not provide a token {"error":"token_not_provided"} .But when i am trying to generate a token by passing email and password in a post request then it fails and give following error.

in AuthManager.php line 137
at Application->Laravel\Lumen\Concerns\{closure}('8', 'Undefined index: provider', 'D:\xamp\htdocs\lumen_api\vendor\illuminate\auth\AuthManager.php', '137', array('name' => 'api', 'config' => array('driver' => 'token'))) in AuthManager.php line 137
at AuthManager->createTokenDriver('api', array('driver' => 'token')) in AuthManager.php line 77
at AuthManager->resolve('api') in AuthManager.php line 57
at AuthManager->guard() in AuthManager.php line 244
at AuthManager->__call('once', array(array('email' => 'testadmin@gmail.com', 'password' => 'password'))) in IlluminateAuthAdapter.php line 39
at AuthManager->once(array('email' => 'testadmin@gmail.com', 'password' => 'password')) in IlluminateAuthAdapter.php line 39
at IlluminateAuthAdapter->byCredentials(array('email' => 'testadmin@gmail.com', 'password' => 'password')) in JWTAuth.php line 108
at JWTAuth->attempt(array('email' => 'testadmin@gmail.com', 'password' => 'password')) in Facade.php line 216
at Facade::__callStatic('attempt', array(array('email' => 'testadmin@gmail.com', 'password' => 'password'))) in AuthController.php line 45
at JWTAuth::attempt(array('email' => 'testadmin@gmail.com', 'password' => 'password')) in AuthController.php line 45
at AuthController->postLogin(object(Request))
at call_user_func_array(array(object(AuthController), 'postLogin'), array(object(Request))) in Container.php line 507
at Container->call(array(object(AuthController), 'postLogin'), array()) in RoutesRequests.php line 581
at Application->callControllerCallable(array(object(AuthController), 'postLogin'), array()) in RoutesRequests.php line 548
at Application->callLumenController(object(AuthController), 'postLogin', array(true, array('uses' => 'App\Http\Controllers\AuthController@postLogin'), array())) in RoutesRequests.php line 521
at Application->callControllerAction(array(true, array('uses' => 'App\Http\Controllers\AuthController@postLogin'), array())) in RoutesRequests.php line 489
at Application->callActionOnArrayBasedRoute(array(true, array('uses' => 'App\Http\Controllers\AuthController@postLogin'), array())) in RoutesRequests.php line 474
at Application->handleFoundRoute(array(true, array('uses' => 'App\Http\Controllers\AuthController@postLogin'), array())) in RoutesRequests.php line 376
at Application->Laravel\Lumen\Concerns\{closure}() in RoutesRequests.php line 624
at Application->sendThroughPipeline(array(), object(Closure)) in RoutesRequests.php line 382
at Application->dispatch(object(Request)) in RoutesRequests.php line 327
at Application->run(object(Request)) in index.php line 29

Here is my Authcontroller code:

namespace App\Http\Controllers;

use Illuminate\Http\Exception\HttpResponseException;
use JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
use Illuminate\Http\Request;
use Illuminate\Http\Response as IlluminateResponse;

class AuthController extends Controller{


/**
 * Handle a login request to the application.
 *
 * @param \Illuminate\Http\Request $request
 * @return \Illuminate\Http\Response
 */
public function postLogin(Request $request)
{
    try
    {
        $this->validate($request, [
            'email' => 'required|email|max:255', 'password' => 'required',
        ]);
    }
    catch (HttpResponseException $e)
    {
        return response()->json([
            'error' => [
                'message'     => 'Invalid auth',
                'status_code' => IlluminateResponse::HTTP_BAD_REQUEST
            ]],
            IlluminateResponse::HTTP_BAD_REQUEST,
            $headers = []
        );
    }

    $credentials = $this->getCredentials($request);

    try
    {
        // attempt to verify the credentials and create a token for the user
        //$customClaims = ['email' => 'rahul.rksaini@gmail.com', 'password' => 'password'];
        if ( ! $token = JWTAuth::attempt($credentials))
        {
            return response()->json(['error' => 'invalid_credentials'], 401);
        }
    }
    catch (JWTException $e)
    {
        // something went wrong whilst attempting to encode the token
        return response()->json(['error' => 'could_not_create_token'], 500);
    }

    // all good so return the token
    return response()->json(compact('token'));
}

/**
 * Get the needed authorization credentials from the request.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return array
 */
protected function getCredentials(Request $request)
{
    return $request->only('email', 'password');
}

}

===================================
my .env file content

APP_ENV=local
APP_DEBUG=true
APP_KEY=swe09w8w7r6t5y4uio321!@wsceszwer

DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=api_db
DB_USERNAME=root
DB_PASSWORD=

CACHE_DRIVER=memcached
QUEUE_DRIVER=sync

JWT_SECRET=cv4d4se065r1td0sw6e8d9za9q102jhes060a3wer

AUTH_DRIVER=jwt
AUTH_MODEL=\App\Models\User
AUTH_TABLE=users

I google it a lot but not get any solution yet. Please help me to figure it out.

thank in advance.

Here is the directory structure of vendor folder

![][vender folder]

R.K.Saini
  • 2,678
  • 1
  • 18
  • 25
  • show your directory structure. Specially the vendor folder where JWT Auth is published – Vishal Sharma Mar 19 '16 at 01:56
  • Also try running `php artisan jwt:generate` and see what is the response you see – Vishal Sharma Mar 19 '16 at 01:58
  • @ Vishal Sh thanks of your comment, I run command php artisan jwt:generate it execuated successfully and give message [token] set successfully but I don't know where it store it in my .env file there is no change in token value and still getting the same error. I am also adding my directory structure in my question. – R.K.Saini Mar 19 '16 at 04:33

1 Answers1

1

You may write your own auth configuration file in config/auth.php (if it doesn't exist, you may create on yourself). See configuration here.

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Authentication Defaults
    |--------------------------------------------------------------------------
    |
    | This option controls the default authentication "guard" and password
    | reset options for your application. You may change these defaults
    | as required, but they're a perfect start for most applications.
    |
    */

    'defaults' => [
        'guard' => env('AUTH_GUARD', 'api'),
    ],

    /*
    |--------------------------------------------------------------------------
    | Authentication Guards
    |--------------------------------------------------------------------------
    |
    | Next, you may define every authentication guard for your application.
    | Of course, a great default configuration has been defined for you
    | here which uses session storage and the Eloquent user provider.
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | Supported: "session"
    |
    | NOTE: "token" driver is not supported in JWT Auth
    |
    */

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

    /*
    |--------------------------------------------------------------------------
    | User Providers
    |--------------------------------------------------------------------------
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | If you have multiple user tables or models you may configure multiple
    | sources which represent each model / table. These sources may then
    | be assigned to any extra authentication guards you have defined.
    |
    | Supported: "database", "eloquent"
    |
    */

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            // We should get model name from JWT configuration
            'model'  => app('config')->get('jwt.user'),
        ],
    ],

];

Fortunately, I create a simple JWT Authentication implemented in Lumen here.

krisanalfa
  • 6,268
  • 2
  • 29
  • 38
  • thanks for your answer it work fine. But can you please explain me why you use 'session' driver instead of 'api' in gaurd. Can you also explain why you are using table "password_resets" I mean how it work. again thanks for your help. – R.K.Saini Mar 27 '16 at 11:57
  • Hi Krisan, I have the same question as the @user3273700, why are you using session here. I thought the whole purpose of JWT was to not use the session. When I try to edit `session` into `jwt` i get the following error: `Auth guard driver [api] is not defined.` – Saif Bechan Apr 07 '16 at 07:55
  • Hi, sorry for late response. So, I dig the library and found that guard must implement `once` and `onceUsingId`, Which is it's declared in `Illuminate\Contracts\Auth\StatefulGuard`. Unfortunately, only `SessionGuard` that implemented this contract. So, I'm using session. But no worry, there's no session stored. We just need it's implementation only. You can see when u're using `file` session driver. There's no session file stored in `storage/sessions` directory. Later, I will change it by creating self-agnostic `AuthGuard`. – krisanalfa Apr 07 '16 at 09:06
  • Thank you for the answer and I get the general idea. I was wondering if the other repo you made could use the same code. https://github.com/krisanalfa/lumen-dingo. This is a combination of Lumen and Dingo, wondering if this needs special instructions. – Saif Bechan Apr 07 '16 at 12:40
  • Also, how would I go about if I wanted to change the user provider from `eloquent` to `database`. When I do the change myself then it tells me that there is no table selected. – Saif Bechan Apr 07 '16 at 13:04
  • @SaifBechan Next time, I hope you would like to create an issue on Github instead of commenting on Stackoverflow. I've updated `lumen-dingo` to work without session provider. To use database authentication, see `config/auth.php` in `providers` section. – krisanalfa Apr 08 '16 at 07:55
  • @KrisanAlfaTimur Yes, I already thought this would be better in github, will do it the proper way next time. I will check out the code. Thank you for the awesome work and I will hop onto github for further issues. – Saif Bechan Apr 11 '16 at 07:21
  • @KrisanAlfaTimur I have created an issue on github, https://github.com/krisanalfa/lumen-dingo/issues/1. I do not know if you want me to create a fork maybe, hope to hear from you soon. – Saif Bechan Apr 12 '16 at 07:22