我需要解决以下问题:我使用Laravel创建了两个应用程序。
https://test.example.org
,并提供了护照实例和所有的用户数据(型号:User
)。https://test.org
API来访问应用程序B,并使用API。应用程序A使用存在于应用程序A中的“ api-user”来获取“公共”数据现在,我想为应用程序B的用户提供一种登录方法。使用应用程序B的所有用户都存在于应用程序A中。因此,登录到应用程序B的用户正在使用保存在应用程序A中的凭据。在应用程序A中对用户所做的所有更改应在应用程序B上可见。
现在我不知道该怎么办。任何想法如何解决这个问题?我可以想象将API调用与
$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();
}
}
但是我不知道是否需要为Application A上的每个用户创建一个client_id
和。在这种情况下,我需要将这些信息存储在某个地方,以便最终在Application B本身上创建一个模型。client_secret
User
最优雅的方法是在应用程序B中使用Laravel Socialite充当应用程序A的OAuth客户端,该应用程序A充当OAuth服务器(使用Laravel Passport)。
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
。
services.php
。例如:'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=...
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');
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句