Err*_*404 2 php laravel laravel-passport
我正在使用 Laravel Passport 来保护我的 REST API。目前,我使用 创建个人访问令牌$user->createToken('APP_NAME')->accessToken,但这些令牌没有过期日期。所以我想创建一个密码访问令牌。我注意到,这些是由该AccessTokenController.issueToken()方法生成的。
但我找不到任何关于如何称呼它的信息。
我目前的解决方案
$input = $request->all();
$user = User::where('email', $input['email'])->first();
if ($user) {
if ($input['password'] == $user->password) {
$token = $user->createToken($this->app_name)->accessToken;
return [
'token' => $token,
'user' => $user
];
} else
return new ResponseGeneratorError('Password mismatch', 400);
} else
return new ResponseGeneratorError('User does not exist', 400);
Run Code Online (Sandbox Code Playgroud)
小智 5
根据上面的评论更新了最新版本 Passport ^10.4 的特征。
<?php
/**
* @author cvaize@gmail.com
* For "laravel/passport@^10.4".
*
* The original is taken from the page /sf/ask/3550924401/
* and redesigned for the latest version "^10.4".
*/
namespace App\Traits;
use App\Domains\Users\User\Models\User;
use DateTimeImmutable;
use Error;
use Exception;
use GuzzleHttp\Psr7\Response;
use Illuminate\Events\Dispatcher;
use Laravel\Passport\Bridge\AccessToken;
use Laravel\Passport\Bridge\AccessTokenRepository;
use Laravel\Passport\Bridge\Client;
use Laravel\Passport\Bridge\ClientRepository;
use Laravel\Passport\Bridge\RefreshTokenRepository;
use Laravel\Passport\Http\Controllers\ConvertsPsrResponses;
use Laravel\Passport\Passport;
use Laravel\Passport\TokenRepository;
use League\OAuth2\Server\CryptKey;
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
use League\OAuth2\Server\Exception\OAuthServerException;
use League\OAuth2\Server\Exception\UniqueTokenIdentifierConstraintViolationException;
use League\OAuth2\Server\ResponseTypes\BearerTokenResponse;
use Psr\Http\Message\ResponseInterface;
use TypeError;
use function time;
# https://github.com/laravel/passport/issues/71
/**
* Trait PassportToken
*
* @package App\Traits
*/
trait PassportToken
{
use ConvertsPsrResponses;
/**
* Generate a new unique identifier.
*
* @param int $length
*
* @return string
* @throws OAuthServerException
*
*/
private function generateUniqueIdentifier($length = 40): string
{
try {
return bin2hex(random_bytes($length));
// @codeCoverageIgnoreStart
} catch (TypeError $e) {
throw OAuthServerException::serverError('An unexpected error has occurred');
} catch (Error $e) {
throw OAuthServerException::serverError('An unexpected error has occurred');
} catch (Exception $e) {
// If you get this message, the CSPRNG failed hard.
throw OAuthServerException::serverError('Could not generate a random string');
}
// @codeCoverageIgnoreEnd
}
private function issueRefreshToken(AccessTokenEntityInterface $accessToken)
{
$maxGenerationAttempts = 10;
$refreshTokenRepository = app(RefreshTokenRepository::class);
$refreshToken = $refreshTokenRepository->getNewRefreshToken();
$refreshToken->setExpiryDateTime((new DateTimeImmutable())->add(Passport::refreshTokensExpireIn()));
$refreshToken->setAccessToken($accessToken);
while ($maxGenerationAttempts-- > 0) {
$refreshToken->setIdentifier($this->generateUniqueIdentifier());
try {
$refreshTokenRepository->persistNewRefreshToken($refreshToken);
return $refreshToken;
} catch (UniqueTokenIdentifierConstraintViolationException $e) {
if ($maxGenerationAttempts === 0) {
throw $e;
}
}
}
}
protected function createPassportTokenByUser(User $user, $clientId, array $scopes = []): array
{
$clientRepository = app(ClientRepository::class);
$client = $clientRepository->getClientEntity($clientId);
$accessToken = new AccessToken($user->getAuthIdentifier(), $scopes, $client);
$accessToken->setIdentifier($this->generateUniqueIdentifier());
$accessToken->setClient(new Client($clientId, null, null));
$accessToken->setExpiryDateTime((new DateTimeImmutable())->add(Passport::tokensExpireIn()));
$accessTokenRepository = new AccessTokenRepository(new TokenRepository(), new Dispatcher());
$accessTokenRepository->persistNewAccessToken($accessToken);
$refreshToken = $this->issueRefreshToken($accessToken);
$privateKey = new CryptKey('file://' . Passport::keyPath('oauth-private.key'), null, false);
$accessToken->setPrivateKey($privateKey);
$expireDateTime = $accessToken->getExpiryDateTime()->getTimestamp();
return [
'token_type' => 'Bearer',
'expires_in' => $expireDateTime - time(),
'access_token' => $accessToken,
'refresh_token' => $refreshToken,
];
}
protected function sendBearerTokenResponse($accessToken, $refreshToken): ResponseInterface
{
$response = new BearerTokenResponse();
$response->setAccessToken($accessToken);
$response->setRefreshToken($refreshToken);
$privateKey = new CryptKey('file://' . Passport::keyPath('oauth-private.key'), null, false);
$response->setPrivateKey($privateKey);
$response->setEncryptionKey(app('encrypter')->getKey());
return $response->generateHttpResponse(new Response);
}
/**
* @param User $user
* @param $clientId
* @param array $scopes
* @param bool $output
* @return \Illuminate\Http\Response|mixed
*/
protected function getBearerTokenByUser(User $user, $clientId, array $scopes = [], bool $output = true): mixed
{
$passportToken = $this->createPassportTokenByUser($user, $clientId, $scopes);
$bearerToken = $this->sendBearerTokenResponse($passportToken['access_token'], $passportToken['refresh_token']);
if ($output) {
$bearerToken = $this->convertResponse($bearerToken);
} else {
$bearerToken = json_decode($bearerToken->getBody()->__toString(), true);
}
return $bearerToken;
}
}
Run Code Online (Sandbox Code Playgroud)