我知道我不是唯一一个走到这一步的人。有谁知道如何在 Laravel(5.3) Passport 中正确实现自定义授权?
或者
有一个很好的链接/教程来参考如何正确地做到这一点?
我知道有这个包:
https://github.com/mikemclin/passport-custom-request-grant
但我要求更多“自己动手”的方法。
先感谢您。
我知道我不是唯一一个走到这一步的人。有谁知道如何在 Laravel(5.3) Passport 中正确实现自定义授权?
或者
有一个很好的链接/教程来参考如何正确地做到这一点?
我知道有这个包:
https://github.com/mikemclin/passport-custom-request-grant
但我要求更多“自己动手”的方法。
先感谢您。
namespace App\Providers;
use App\Auth\Grants\FacebookGrant;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Laravel\Passport\Bridge\RefreshTokenRepository;
use Laravel\Passport\Passport;
use League\OAuth2\Server\AuthorizationServer;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
app(AuthorizationServer::class)->enableGrantType(
$this->makeFacebookGrant(), Passport::tokensExpireIn()
);
Passport::routes();
//
}
/**
* Create and configure a Facebook grant instance.
*
* @return FacebookGrant
*/
protected function makeFacebookGrant()
{
$grant = new FacebookGrant(
$this->app->make(RefreshTokenRepository::class)
);
$grant->setRefreshTokenTTL(Passport::refreshTokensExpireIn());
return $grant;
}
}
编辑:抱歉只发布此代码,我不知道此代码对您有多大用处。
好吧,我将在这里留下我的 FacebookGrant 实现,希望这对某人有所帮助。
<?php
namespace App\Auth\Grants;
use Illuminate\Http\Request;
use Laravel\Passport\Bridge\User;
use League\OAuth2\Server\Entities\ClientEntityInterface;
use League\OAuth2\Server\Entities\UserEntityInterface;
use League\OAuth2\Server\Exception\OAuthServerException;
use League\OAuth2\Server\Grant\AbstractGrant;
use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
use League\OAuth2\Server\RequestEvent;
use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface;
use Psr\Http\Message\ServerRequestInterface;
use RuntimeException;
class FacebookGrant extends AbstractGrant
{
/**
* @param RefreshTokenRepositoryInterface $refreshTokenRepository
*/
public function __construct(
RefreshTokenRepositoryInterface $refreshTokenRepository
) {
$this->setRefreshTokenRepository($refreshTokenRepository);
$this->refreshTokenTTL = new \DateInterval('P1M');
}
/**
* {@inheritdoc}
*/
public function respondToAccessTokenRequest(
ServerRequestInterface $request,
ResponseTypeInterface $responseType,
\DateInterval $accessTokenTTL
) {
// Validate request
$client = $this->validateClient($request);
$scopes = $this->validateScopes($this->getRequestParameter('scope', $request));
$user = $this->validateUser($request, $client);
// Finalize the requested scopes
$scopes = $this->scopeRepository->finalizeScopes($scopes, $this->getIdentifier(), $client, $user->getIdentifier());
// Issue and persist new tokens
$accessToken = $this->issueAccessToken($accessTokenTTL, $client, $user->getIdentifier(), $scopes);
$refreshToken = $this->issueRefreshToken($accessToken);
// Inject tokens into response
$responseType->setAccessToken($accessToken);
$responseType->setRefreshToken($refreshToken);
return $responseType;
}
/**
* @param ServerRequestInterface $request
*
* @return UserEntityInterface
* @throws OAuthServerException
*/
protected function validateUser(ServerRequestInterface $request, ClientEntityInterface $client)
{
$facebookId = $this->getRequestParameter('facebook_id', $request);
if (is_null($facebookId)) {
throw OAuthServerException::invalidRequest('facebook_id');
}
$email = $this->getRequestParameter('email', $request);
if (is_null($email)) {
throw OAuthServerException::invalidRequest('email');
}
$user = $this->getUserEntityByUserFacebookId(
$facebookId,
$email,
$this->getIdentifier(),
$client
);
if ($user instanceof UserEntityInterface === false) {
$this->getEmitter()->emit(new RequestEvent(RequestEvent::USER_AUTHENTICATION_FAILED, $request));
throw OAuthServerException::invalidCredentials();
}
return $user;
}
/**
* Retrieve a user by the given Facebook Id.
*
* @param string $facebookId
* @param string $email
* @param string $grantType
* @param \League\OAuth2\Server\Entities\ClientEntityInterface $clientEntity
*
* @return \Laravel\Passport\Bridge\User|null
* @throws \League\OAuth2\Server\Exception\OAuthServerException
*/
private function getUserEntityByUserFacebookId($facebookId, $email, $grantType, ClientEntityInterface $clientEntity)
{
$provider = config('auth.guards.api.provider');
if (is_null($model = config('auth.providers.'.$provider.'.model'))) {
throw new RuntimeException('Unable to determine authentication model from configuration.');
}
$user = (new $model)->where('facebook_id', $facebookId)->first();
if (is_null($user)) {
$user = (new $model)->where('email', $email)->first();
if (is_null($user)) {
return;
}
// Now that we retrieved the user with the email, we need to update it with
// the given facebook id. So the user account will be linked correctly.
$user->facebook_id = $facebookId;
$user->save();
}
return new User($user->getAuthIdentifier());
}
/**
* {@inheritdoc}
*/
public function getIdentifier()
{
return 'facebook';
}
}
我不确定自定义授予是什么意思,但是您可以使用护照服务进行密码授予,可以根据需要进行自定义。
参考:https ://laravel.com/docs/5.3/passport#password-grant-tokens
为了提供更多信息,您将获得一个client_id和client_secret ,您的 api 的所有用户都将使用他们的密码和电子邮件来获取access_token和refresh_token,然后您可以通过中间件添加功能来自定义该过程。
例如,您可以检查一些自定义标头(如果存在)或根据请求更改数据库以执行进一步查询等。
也许我对您的问题有完全错误的想法,如果是这种情况,请详细说明您的需求。