我需要解决以下问题:我使用 Laravel 创建了两个应用程序。
https://test.example.org
联系到并提供护照实例和所有用户数据(型号:User
)。 https://test.org
联系到并使用 API 应用程序 A 提供使用存在于 中的“api-user”应用程序 A 获取“公共(public)”数据 现在我想为的用户提供一个登录方法。应用 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();
}
}
但我不明白,我是否需要创建一个
client_id
和 client_secret
对于 上的每个用户应用程序 A .如果是这种情况,我需要将这些信息存储在某个地方,以便我最终创建一个 User
关于 的模型应用 B 本身。我的问题是:
最佳答案
最优雅的方法是在您的 中使用 Laravel Socialite应用 B 充当 的 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 和客户端 secret ,因为稍后您将需要它们。
您还需要一个 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
文件,为您在 中创建的 Passport 客户端设置客户端 ID 和密码应用程序 A :PASSPORT_CLIENT_ID=...
PASSPORT_CLIENT_SECRET=...
Application A
使用自定义提供程序扩展 Socialite . 创建一个
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'])
);
});
}
现在您已准备好在您的 login controller 中使用您的自定义 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');
关于laravel - 使用 Laravel Passport 登录 3rd 方网站,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60259684/