laravel - 使用 Laravel Passport 登录 3rd 方网站

标签 laravel laravel-passport laravel-6 laravel-6.2

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

  • 应用程序 A 可以通过 https://test.example.org 联系到并提供护照实例和所有用户数据(型号:User)。
  • 应用 B 可以通过 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_idclient_secret对于 上的每个用户应用程序 A .如果是这种情况,我需要将这些信息存储在某个地方,以便我最终创建一个 User关于 的模型应用 B 本身。

    我的问题是:
  • 如何登录 上存在的用户应用程序 A 应用 B 最优雅的方式?
  • 是否可以选择从客户端使用 Laravel/Socialite( 应用程序 B )?
  • 最佳答案

    最优雅的方法是在您的 中使用 Laravel Socialite应用 B 充当 的 OAuth 客户端应用程序 A 它充当 OAuth 服务器(使用 Laravel Passport)。

  • 应用程序 A ,您需要create a client在护照上为您 应用 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 和客户端 secret ,因为稍后您将需要它们。

    您还需要一个 API 端点来提供经过身份验证的用户的详细信息,例如https://test.example.org/user .
  • 应用 B , 之后 installing Laravel Socialite,你需要为设置凭据应用程序 A 在您的 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/

    相关文章:

    laravel - 如何在 Laravel 6 中使用 Font Awesome 5 图标

    json - Laravel:更新嵌套的 json 对象

    php - Laravel 分页一次一个模型

    PHP Laravel 数据库 : Get all entries from one table + more

    vue.js - Laravel 护照(看不懂)

    angular - Laravel Passport 和 Angular 在 api/登录路线上给了我未经授权的权限,但在 postman 上工作正常?

    laravel - 是否可以在Laravel Passport中禁用路线?

    php - 如何在 Laravel 5.1 中使用 NOT FIND_IN_SET?

    php - Laravel 5 IoC 类型提示不起作用

    Laravel 在 Eloquent 中使用 with() 方法时出错