#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;
}