使用Laravel Passport登录第三方网站



我需要解决以下问题:我使用Laravel创建了两个应用程序。

  • 应用程序A可以通过https://test.example.org访问,并提供护照实例和所有用户数据(型号:User(
  • 应用程序B可以通过https://test.org访问,并使用API程序A提供的"API-user"来获取"公共"数据

现在我想为应用程序B的用户提供一种登录方法。所有使用应用程序B的用户都存在于程序A中。因此,登录应用程序B的用户正在使用保存在程序a中的凭据。在应用程序A中对用户所做的所有更改都应在应用程序B上可见。

现在我想知道我该怎么做。知道怎么解决这个问题吗?我可以想象使用带有的API-call

$client = $this->client;
try {
return $client->request('POST',
'https://'.config('server').'/oauth/token', [
'headers'     => [
'cache-control' => 'no-cache',
'Content-Type'  => 'application/x-www-form-urlencoded',
],
'form_params' => [
'client_id'     => ...,
'client_secret' => ...,
'grant_type'    => 'password',
'username'      => $users-username,
'password'      => $users-password,
],
]);
} catch (BadResponseException $e) {
return $e->getResponse();
}
}

但我不知道是否需要为应用程序a上的每个用户创建client_idclient_secret。如果是这种情况,我需要将这些信息存储在某个地方,以便最终在应用程序B本身上创建User模型。

我的问题是:

  • 如何以最优雅的方式将应用程序A上现有的用户登录到程序B
  • 是否可以从客户端使用Laravel/Socialite(应用程序B(

最优雅的方法是在应用程序B中使用Laravel Socialite作为的应用程序A的OAuth客户端,该应用程序充当OAuth服务器(使用Laraver Passport(。

  1. 应用程序A上,您需要在Passport上为的应用程序B创建一个客户端:
php artisan passport:client --password

首先,您将被问到Which user ID should the client be assigned to?。按enter键,因为您不想将客户端限制为特定用户。

然后,您将被要求为您的客户提供一个名称,您应该输入类似Application B的内容。

最后,您将被要求提供客户端的重定向URL。您应该输入https://test.org/oauth/callback,这是Socialite在用户通过身份验证后用于重定向回用户的URL。

如果您需要在您的机器上进行测试,请输入您的本地域,例如https://application-b.test/oauth/callback

创建客户端后,请对客户端ID和客户端保密,因为以后需要它们。

您还需要一个API端点来提供已验证用户的详细信息,例如https://test.example.org/user

  1. 应用程序B上,安装Laravel Socialite后,您需要在services.php配置文件中设置程序A的凭据。例如:
'passport' => [
'client_id' => env('PASSPORT_CLIENT_ID'),
'client_secret' => env('PASSPORT_CLIENT_SECRET'),
'redirect' => 'oauth/callback',
],

.env文件中,为您在应用程序A:中创建的Passport客户端设置客户端ID和机密

PASSPORT_CLIENT_ID=...
PASSPORT_CLIENT_SECRET=...
  1. 现在您需要使用Application A的自定义提供程序来扩展Socialite

app/Socialite目录中创建一个PassportProvider类(如果愿意,可以在app中的任何位置创建(。

<?php
namespace AppSocialite;
use LaravelSocialiteTwoAbstractProvider;
use LaravelSocialiteTwoProviderInterface;
use LaravelSocialiteTwoUser;
use IlluminateSupportArr;
class PassportProvider extends AbstractProvider implements ProviderInterface
{
/**
* {@inheritdoc}
*/
protected function getAuthUrl($state)
{
return $this->buildAuthUrlFromBase('https://test.example.org/oauth/authorize', $state);
}
/**
* {@inheritdoc}
*/
protected function getTokenUrl()
{
return 'https://test.example.org/oauth/token';
}
/**
* {@inheritdoc}
*/
protected function getUserByToken($token)
{
$response = $this->getHttpClient()->get(
'https://test.example.org/user',
$this->getRequestOptions($token)
);
return json_decode($response->getBody(), true);
}
/**
* {@inheritdoc}
*/
protected function mapUserToObject(array $user)
{
return (new User)->setRaw($user)->map([
'id' => $user['id'],
'name' => Arr::get($user, 'name'),
'email' => Arr::get($user, 'email'),
]);
}
/**
* Get the default options for an HTTP request.
*
* @param string $token
* @return array
*/
protected function getRequestOptions($token)
{
return [
'headers' => [
'Accept' => 'application/json',
'Authorization' => 'token '.$token,
],
];
}
}

接下来,在您的ApplicationServiceProvider(或单独的服务提供商(中,添加以下内容:

use AppSocialitePassportProvider;
use IlluminateSupportFacadesURL;
use LaravelSocialiteFacadesSocialite;
public function boot()
{
Socialite::extend('passport', function (function ($app) {
$config = $app['config']['services.passport'];
return new PassportProvider(
$app['request'],
$config['client_id'],
$config['client_secret'],
URL::to($config['redirect'])
);
});
}

现在,您可以在客户端应用程序的登录控制器中使用自定义Socialite提供商:

<?php
namespace AppHttpControllersAuth;
use AppHttpControllersController;
use LaravelSocialiteFacadesSocialite;
class LoginController extends Controller
{
/**
* Redirect the user to the GitHub authentication page.
*
* @return IlluminateHttpRedirectResponse
*/
public function redirectToProvider()
{
return Socialite::driver('passport')->redirect();
}
/**
* Obtain the user information from GitHub.
*
* @return IlluminateHttpResponse
*/
public function handleProviderCallback()
{
$user = Socialite::driver('passport')->user();
}
}

不要忘记在routes/web.php文件中注册登录路线:

Route::get('oauth/redirect', 'AuthLoginController@redirectToProvider');
Route::get('oauth/callback', 'AuthLoginController@handleProviderCallback');

A。您只能为应用程序B创建一个client_id和client_secret
B。使用上面所写的Passport
C。你可以,但你需要手动设置它,我不确定这是个好主意,更好的方法是将它重定向到应用程序a UI(如果是web(或直接联系应用程序a(如果是移动设备(,让它自己处理。

有两种解决方案

1。如果您只需要应用程序A数据库详细信息,请在的应用程序B中创建多个数据库连接

https://fideloper.com/laravel-multiple-database-connections

2。如果您想访问应用程序A端点,请为您的两个应用程序保留相同的文件storage/oauth-public.key、storage/outh-private.key,以便A应用程序可以轻松地对B应用程序授权令牌进行身份验证。

最新更新