1

我正在使用 Laravel 8 开发一个网页,但在通过 Patreon API 的 id 获取赞助人详细信息时遇到问题。这是我的用例。

我在我的网页中添加了“使用 Patreon 登录”选项,效果很好。当有人成功登录 Patreon 时,我会存储她/他的 Patreon id 并设置记住令牌以在她/他下次访问我的页面时自动登录该会员。

第一次登录过程很好。当我的顾客下次访问我的页面时,就会出现问题。因为我想在让她/他看到所有内容之前检查我是否收到任何付款。这就是为什么我需要从中间件获取赞助人详细信息的原因。为此,我尝试了:

  • fetch_user() 返回我的帐户详细信息而不是登录用户。
  • fetch_user() 使用当有人登录时从 Patreon 返回的访问令牌,返回未经授权的。
  • fetch_member_details() 不适用于我传递的 id,它是一个像 5484646 这样的整数,因为它需要一个非常长的字符串,比如 55153fds-f45fd5sfs-fds42ds,我不知道它是什么。
  • fetch_page_of_members_from_campaign() 和 fetch_member_details() 一起获取正确的 ID,但是获取数据需要很长时间,这是不可接受的。

那么,怎么做呢?

4

2 回答 2

2

https://further-reading.net/2020/06/getting-names-of-your-patreon-patrons-by-tier/

这可能很有用。我相信,对此没有直接的单一 API,但您可以 -

  1. 首先获取所有活动/层级数据
  2. 然后为每个活动/层级获取顾客
于 2021-03-19T17:59:46.613 回答
0

我喜欢为需要帮助的人回答我的问题。

首先,我使用的是 Patreon的官方PHP 包

我创建了一个中间件来检查用户是否应该再次获得授权。为了防止每次都执行相同的进程,我为 users 表设置了 timeout 并检查它是否还有时间过期。如果是这样,则无需执行任何操作。当然,这是我的用例,但如果没有那个解释,代码的某些部分对你来说可能是无稽之谈。

// App\Http\Middleware\AuthenticateMember.php


public function handle(Request $request, Closure $next)
{
    if (!Auth::check()) {
        return $next($request);
    }
    if (Carbon::parse(Auth::user()->timeout)->isFuture()) {
        return $next($request);
    }
    $this->refreshCredentials();
    return $next($request);
}

如果将来没有“超时”,refreshCredentials则将调用方法。这是一个方法,它将触发将 AuthGatewayContract 绑定到服务容器。

//  App\Trait\Users.php


public function refreshCredentials()
{
    $gateway = App::make('App\Services\AuthGatewaysContract');
    $gateway->ensureUserStillAuthenticated();
}

public function handleUserRecord($user)
{
    return User::updateOrCreate([
        'email' => $user['email']
    ], $user);
}

public function attemptToLogin($user, $remember = true)
{
    Auth::login($user, $remember);
    event(new Registered($user));
}

这是绑定的工作原理:

//  App\Providers\AppServiceProvider.php


public function register()
{
    $this->app->singleton(AuthGatewaysContract::class, function () {
        $routeParts = explode('/', url()->current());
        $gateway = array_pop($routeParts); // this is how I know which "Login with ..." button is clicked.
        $isGateway = Gateway::where('name', $gateway)->first();
        $gateway = $isGateway ? ucfirst($gateway) : ucfirst(Auth::user()->gateway->name);
        $class = "\App\Services\AuthGateways\\$gateway";
        return new $class();
    });
}

所以 Patreon.php 现在是活动网关,ensureUserStillAuthenticated可以调用:

// App\Services\AuthGateways\Patreon.php


public function ensureUserStillAuthenticated()
{
    $this->authenticate([
        'access_token' => Auth::user()->access_token,
        'refresh_token' => Auth::user()->refresh_token,
    ]);
}

private function authenticate($tokens)
{
    $patron = $this->fetchUserFromGateway($tokens);
    $user = $this->handleResponseData($patron, $tokens);
    $user = $this->handleUserRecord($user);
    return $this->attemptToLogin($user);
}

private function fetchUserFromGateway($tokens)
{
    // This is the only function that communicate with Patreon-php package.
    $api_client = new API($tokens['access_token']);
    return $api_client->fetch_user();
}

private function handleResponseData($data, $tokens)
{
    return [
        'name' => $data['data']['attributes']['full_name'],
        'email' => $data['data']['attributes']['email'],
        'password' => Hash::make(Str::random(24)),
        'role_id' => $this->assignRoleId($data),
        'payment_id' => Payment::where('name', 'patreon')->first()->id,
        'gateway_id' => Gateway::where('name', 'patreon')->first()->id,
        'access_token' => $tokens['access_token'],
        'refresh_token' => $tokens['refresh_token'],
        'timeout' => Carbon::today()->addMonth()->toDateString()
    ];
}
于 2021-04-22T20:27:26.040 回答