Самый элегантный способ - использовать Laravel Socialite в приложении B для работы в качестве клиента OAuth для приложения A , действующего как сервер OAuth (с использованием Laravel Паспорт).
- Вкл. Приложение A , вам необходимо создать клиент в Паспорте для вашего Приложения B :
php artisan passport:client --password
Сначала вас спросят Which user ID should the client be assigned to?
. Нажмите ввод, поскольку вы не хотите ограничивать клиента определенным c пользователем.
Затем вам будет предложено указать имя вашего клиента, вам следует ввести что-то вроде Application B
.
Наконец, вас попросят указать URL-адрес перенаправления вашего клиента. Вы должны ввести https://test.org/oauth/callback
, то есть URL-адрес, который Socialite будет использовать для перенаправления пользователей после их аутентификации.
Если вам нужно проверить это на своем компьютере, введите свой локальный домен, например, https://application-b.test/oauth/callback
.
После того, как клиент будет создан, держите в секрете идентификатор клиента и клиента, так как они понадобятся вам позже.
Вам также понадобится конечная точка API для предоставления подробностей для аутентифицированного пользователя,. например, https://test.example.org/user
.
Вкл.
Приложение B , после
установки Laravel Socialite необходимо установить учетные данные для
Приложения A в файле конфигурации
services.php
. Например:
'passport' => [
'client_id' => env('PASSPORT_CLIENT_ID'),
'client_secret' => env('PASSPORT_CLIENT_SECRET'),
'redirect' => 'oauth/callback',
],
В своем файле .env
укажите идентификатор клиента и секретный ключ для клиента Passport, который вы создали в Приложении A :
PASSPORT_CLIENT_ID=...
PASSPORT_CLIENT_SECRET=...
Теперь вам нужно расширить Socialite с помощью специального провайдера для
Application A
.
Создать класс PassportProvider
в каталоге app/Socialite
(или в любом месте внутри app
, если хотите) .
<?php
namespace App\Socialite;
use Laravel\Socialite\Two\AbstractProvider;
use Laravel\Socialite\Two\ProviderInterface;
use Laravel\Socialite\Two\User;
use Illuminate\Support\Arr;
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 App\Socialite\PassportProvider;
use Illuminate\Support\Facades\URL;
use Laravel\Socialite\Facades\Socialite;
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 App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Laravel\Socialite\Facades\Socialite;
class LoginController extends Controller
{
/**
* Redirect the user to the GitHub authentication page.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function redirectToProvider()
{
return Socialite::driver('passport')->redirect();
}
/**
* Obtain the user information from GitHub.
*
* @return \Illuminate\Http\Response
*/
public function handleProviderCallback()
{
$user = Socialite::driver('passport')->user();
}
}
Не забудьте зарегистрировать маршруты входа в ваш routes/web.php
файл:
Route::get('oauth/redirect', 'Auth\LoginController@redirectToProvider');
Route::get('oauth/callback', 'Auth\LoginController@handleProviderCallback');