Не удалось пройти аутентификацию с ошибкой недопустимого токена в dingo / api с jwt-auth

#php #api #laravel #dingo-api

#php #API #laravel #dingo-api

Вопрос:

Я использую dingo / api (который имеет встроенную поддержку jwt-auth) для создания API.

Предположим, что это мои маршруты :

 $api->group(['prefix' => 'auth', 'namespace' => 'Auth'], function ($api) {
            $api->post('checkPhone', 'LoginController@checkPhone');

            //Protected Endpoints
            $api->group(['middleware' => 'api.auth'], function ($api) {
                $api->post('sendCode', 'LoginController@sendCode');
                $api->post('verifyCode', 'LoginController@verifyCode');

            });
        });
  

checkPhone метод, который имеет задачу авторизации и создания токена, похож :

 public function checkPhone (Request $request)
        {
            $phone_number = $request->get('phone_number');
            if (User::where('phone_number', $phone_number)->exists()) {

                $user = User::where('phone_number', $phone_number)->first();

                $user->injectToken();

                return $this->response->item($user, new UserTransformer);

            } else {
                return $this->response->error('Not Found Phone Number', 404);
            }
        }
  

И injectToken() метод в User модели является :

 public function injectToken ()
        {
            $this->token = JWTAuth::fromUser($this);
            return $this;
        } 
  

Создание токена работает нормально.

Но когда я отправляю его на защищенную конечную точку, всегда Unable to authenticate with invalid token происходит.

Метод действия защищенной конечной точки является :

 public function verifyCode (Request $request)
        {
            $phone_number = $request->get('phone_number');
            $user_code    = $request->get('user_code');

            $user = User::wherePhoneNumber($phone_number)->first();

            if ($user) {
                $lastCode = $user->codes()->latest()->first();

                if (Carbon::now() > $lastCode->expire_time) {
                    return $this->response->error('Code Is Expired', 500);
                } else {
                    $code = $lastCode->code;

                    if ($user_code == $code) {

                        $user->update(['status' => true]);

                        return ['success' => true];
                    } else {
                        return $this->response->error('Wrong Code', 500);
                    }
                }
            } else {
                return $this->response->error('User Not Found', 404);
            }
        }
  

Я использовал PostMan в качестве клиента API и отправлял сгенерированные токены в виде заголовка, подобного этому :

 Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI5ODkxMzk2MTYyNDYiLCJpc3MiOiJodHRwOlwvXC9hcGkucGFycy1hcHAuZGV2XC92MVwvYXV0aFwvY2hlY2tQaG9uZSIsImlhdCI6MTQ3NzEyMTI0MCwiZXhwIjoxNDc3MTI0ODQwLCJuYmYiOjE0NzcxMjEyNDAsImp0aSI6IjNiMjJlMjUxMTk4NzZmMzdjYWE5OThhM2JiZWI2YWM2In0.EEj32BoH0URg2Drwc22_CU8ll--puQT3Q1NNHC0LWW4
  

Я не могу найти решение после многих поисков в Интернете и связанных репозиториях.

В чем проблема, по вашему мнению?

Обновить :

Я обнаружил, что ошибка not found относится к конструктору LoginController, который предлагает laravel :

 public function __construct ()
        {
            $this->middleware('guest', ['except' => 'logout']);
        }
  

потому что, когда я прокомментировал $this->middleware('guest', ['except' => 'logout']); , все сработало.
Но если я удалю эту строку, это правильно?
Какой должна быть эта строка для API?

Комментарии:

1. $api-> версия (‘v1’, [‘middleware’ => ‘api.auth’], функция ($api) { $api->get(‘user’, функция () { $user = app(‘Dingo Api AuthAuth’)-> user(); возвращает $user; }); }); проверять аутентифицированных пользователей следующим образом

2. @Jagadesha NH, я попробовал это, и произошла ошибка Failed to authenticate because of bad credentials or an invalid authorization header .

3.github.com/tymondesigns/jwt-auth/issues/16 github.com/dingo/api/issues/325 проверьте эти ссылки

4. Я добавил RewriteCond %{HTTP:Authorization} ^(.*) RewriteRule .* - [e=HTTP_AUTHORIZATION:%1] в htaccess, но при отправке запросов на защищенную конечную точку 404 Not Found возникает ошибка.

5. @Jagadesha NH, я обнаружил, что заголовок авторизации дескриптора был в файле .htaccess последней версии laravel (5.3.19), поэтому не нужно добавлять его снова. но проблема еще не решена

Ответ №1:

обновление моего config/api.php это сделало свое дело

 // config/api.php
...
  'auth' => [
        'jwt' => 'DingoApiAuthProviderJWT'
    ],
...  

Ответ №2:

Как я упоминал ранее в качестве примечания к обновлению, проблема заключалась в том, что я использовал checkPhone и verifyCode в LoginController, у которого есть проверка для guest в его конструкторе.

И поскольку guest промежуточное программное обеспечение ссылается на AppHttpMiddlewareRedirectIfAuthenticated::class и перенаправляет зарегистрированного пользователя в /home каталог, а я этого не создавал, это 404 error произошло.

Теперь я просто перенес эти методы в UserController без какого-либо промежуточного программного обеспечения в его конструкторе.

Ответ №3:

Всегда стоит прочитать исходный код, чтобы увидеть, что происходит. Ответ: The ожидает идентификатор поставщика аутентификации для извлечения пользователя.

 /**
 * Authenticate request with a JWT.
 *
 * @param IlluminateHttpRequest $request
 * @param DingoApiRoutingRoute $route
 *
 * @return mixed
 */
public function authenticate(Request $request, Route $route)
{
    $token = $this->getToken($request);

    try {
        if (! $user = $this->auth->setToken($token)->authenticate()) {
            throw new UnauthorizedHttpException('JWTAuth', 'Unable to authenticate with invalid token.');
        }
    } catch (JWTException $exception) {
        throw new UnauthorizedHttpException('JWTAuth', $exception->getMessage(), $exception);
    }

    return $user;
}