首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Laravel护照登录第三方网站

使用Laravel护照登录第三方网站
EN

Stack Overflow用户
提问于 2020-02-17 09:46:04
回答 3查看 2K关注 0票数 4

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

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

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

现在我想知道我怎么能做到这一点。知道怎么解决这个问题吗?我可以想象使用API-调用

代码语言:javascript
复制
        $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应用程序A上的每个用户创建一个。如果是这样的话,我需要将这些信息存储在某个地方,这样我就可以在Application B本身上创建一个模型。

我的问题是:

  • 如何以最优雅的方式将应用程序A上的用户登录到应用程序B
  • 从客户端使用Laravel/Socialite (Application B)是一种选择吗?
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-03-09 19:26:39

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

  1. 应用程序A上,您需要为应用程序B在护照上设置创建一个客户端
代码语言:javascript
复制
php artisan passport:client --password

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

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

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

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

创建客户端后,将客户端ID和客户端保密,因为您稍后将需要它们。

您还需要一个API端点来为经过身份验证的用户.e.g提供详细信息。https://test.example.org/user

  1. 应用程序B上,在安装 Laravel社会名流之后,您需要在services.php配置文件中为应用程序A设置凭据。例如:
代码语言:javascript
复制
'passport' => [
    'client_id' => env('PASSPORT_CLIENT_ID'),
    'client_secret' => env('PASSPORT_CLIENT_SECRET'),
    'redirect' => 'oauth/callback',
],

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

代码语言:javascript
复制
PASSPORT_CLIENT_ID=...
PASSPORT_CLIENT_SECRET=...
  1. 现在,您需要使用Application A的自定义提供程序来扩展社交功能。

PassportProvider目录中创建一个app/Socialite类(如果您愿意的话,可以在app中的任何地方创建)。

代码语言:javascript
复制
<?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 (或单独的服务提供者)中添加以下内容:

代码语言:javascript
复制
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'])
        );
    });
}

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

代码语言:javascript
复制
<?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文件中注册登录路由:

代码语言:javascript
复制
Route::get('oauth/redirect', 'Auth\LoginController@redirectToProvider');
Route::get('oauth/callback', 'Auth\LoginController@handleProviderCallback');
票数 8
EN

Stack Overflow用户

发布于 2020-03-05 15:42:17

答:您将只为应用程序B创建一个client_id和client_secret

B.使用上面写的护照

你可以,但你需要手动设置它--我不确定这是个好主意,更好的办法是将它重定向到应用程序A用户界面(在web情况下),或者直接联系应用程序A(在移动的情况下),让它自己处理。

票数 0
EN

Stack Overflow用户

发布于 2020-03-09 10:40:40

有两种解决方案

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

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

2.如果您想访问应用程序A端点,而不是为两个应用程序保留相同的文件存储/OAuth-public.key,那么应用程序A可以很容易地验证应用程序B授权令牌。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60259684

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档