@Maria_Gavrilova

Как в laravel passport создать refresh_token?

Здравствуйте. Я пишу api-аутентификацию на основе laravel passport. Сейчас код метода login выгляди так -
public function login(Request $request)
    {
        $request->validate([
            'email' => 'required|string|email',
            'password' => 'required|string|min:6'
        ]);

        $credentials = request(['email', 'password']);

        if (!Auth::attempt($credentials))
            return response()->json([
                'message' => 'Unauthorized'
            ], 401);

        $user = $request->user();
        $tokenResult = $user->createToken('Personal Access Token');
        $token = $tokenResult->token;

        $token->save();

        return response()->json([
            'access_token' => $tokenResult->accessToken,
            'token_type' => 'Bearer',
            'expires_at' => Carbon::parse(
                $tokenResult->token->expires_at
            )->toDateTimeString()
        ]);
    }


Я бы хотела в этом методе создавать также refresh_token и выдавать пользователю здесь и access_token и refresh_token. Access_token дейсствует у меня 1 день. На след. день при заходе пользователю сейчас снова придётся вводить email и пароль. А если бы я выдавала и refresh_token здесь, который действителен две недели, то при заходе пользователя на след день, при получении ошибки авторизации он бы обращался второй раз уже с refresh-токеном и авторизовывался не вводя никакие пароли. Клиенты у меня и в вебе и на андроид и ios.

В документации написано, что Authorization Code нужно какой-то получать через редиректы юзера. А попроще нельзя создавать refresh_token? Просто при вводе пользователем в первый раз email и пароль? Так же просто как я создаю access-токен? Подскажите пожалуйста.
  • Вопрос задан
  • 121 просмотр
Решения вопроса 1
greabock
@greabock
Могу
1. По умолчанию, персональные токены выдаются сроком на 1 год. (нужно ли беспокоится о времени истечения?)

2. Персональные токены - это скорее "хак", который позволяет обойти стандартный флоу OAuth 2. Обычно он используется для упрощения доступа к апи, или персональных экспериментов.

3. Правильный способ сделать то, что вы ( как я предполагаю) хотите, это запросить токен для password grant

use GuzzleHttp\Psr7\ServerRequest as GuzzleRequest;
use GuzzleHttp\Psr7\Response as GuzzleResponse;
use League\OAuth2\Server\AuthorizationServer;
use Illuminate\Http\Response;
use Illuminate\Http\Request;


$server = app(AuthorizationServer::class);

$psrReponse = $server->respondToAccessTokenRequest((new GuzzleRequest('POST', ''))->withParsedBody([
    'grant_type'    => 'password',
    'client_id'     => '2' // Или какой клиент у вас там за гранты паролей отвечает,
    'client_secret' => '***',
    'username'      => 'god@skies.com',
    'password'      => 'my-very-strong-password',
    'scope'         => '',
]), new GuzzleResponse());
// Можно сразу запросить на вход \Psr\Http\Message\ServerRequestInterface - лара умеет такое инжектить
// Я накидал его руками - для наглядности
// Это могут быть любые psr7 совместимые объекты Request и Response, не только Guzzle. 
// Например Zend\Diactoros (его ижектит лара) тоже подойдет.

// Ну а здесь уже конвертируем ответ в ларовский
// Ответ будет содержать token_type, access_token, expires_in и refresh_token 
// expires_in содержит время жизни токена в секундах
// Например, по умолчанию для одного года это будет 60*60*24*366 = 31622400
return new Response(
    $psrReponse ->getBody(),
    $psrReponse ->getStatusCode(),
    $psrReponse ->getHeaders()
 );


Здесь не описана обработка ошибок, так как я предполагаю, что данный сценарий выходит за рамки OAuth спецификации и ответы с ошибками имеют право ей не соответствовать. Это я оставлю на ваше усмотрение.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы