4

私は正常に動作している Yii2 Filsh Oauth サーバーを使用していますが、ログインすると、デフォルトのフィールドで AccessToken が生成されます。

{
  "access_token": "f3389e81c234276967079b2293795fc9104a2fac",
  "expires_in": 86400,
  "token_type": "Bearer",
  "user_id": 9,
  "scope": null,
  "refresh_token": "851464a210f56bb831da378a43e1016bd3e765d7",
}

しかし、次のような応答にユーザー情報を追加する必要がありました

{
  "access_token": "f3389e81c234276967079b2293795fc9104a2fac",
  "expires_in": 86400,
  "token_type": "Bearer",
  "scope": null,
  "refresh_token": "851464a210f56bb831da378a43e1016bd3e765d7",
  "user": {
    "id": 9,
    "first_name": "Test",
    "last_name": "Test2",
    "username": "test",
    "email": "test@gmail.com",
    "status": 1,
    "dob": "20-08-1990",
    "gender": "Male",
   }
}

私は自分の要件を満たすためにbshafferコアライブラリファイルをカスタマイズした奇妙な回避策を思いつきました(これは良いアプローチではありません)。私がしたことは、ユーザーモデルの次の行を変更しました:

return ['user_id' => $user->getId()];

これに

return ['user_id' => [$user->getId(), $userObject]]; //I get all user info in $userObject and passed an array with two fields

私は単一の代わりに配列を渡している$user->getId()ので、このパスで利用可能なbshafferライブラリファイルAccessToken.phpを変更する必要がありました: vendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseType/AccessToken.php76行目

私はこれを変更しました:

public function createAccessToken($client_id, $user_id, $scope = null, $includeRefreshToken = true)
{
  $token = array(
        "access_token" => $this->generateAccessToken(),
        "expires_in" => $this->config['access_lifetime'],
        "token_type" => $this->config['token_type'],
        "user_id" => $user_id,
        "scope" => $scope
    );

  $this->tokenStorage->setAccessToken($token["access_token"], $client_id, $user_id, $this->config['access_lifetime'] ? time() + $this->config['access_lifetime'] : null, $scope);

  if ($includeRefreshToken && $this->refreshStorage) {
        $token["refresh_token"] = $this->generateRefreshToken();
        $expires = 0;
        if ($this->config['refresh_token_lifetime'] > 0) {
            $expires = time() + $this->config['refresh_token_lifetime'];
        }
        $this->refreshStorage->setRefreshToken($token['refresh_token'], $client_id, $user_id, $expires, $scope);
    }
  return $token;
}

これに:

public function createAccessToken($client_id, $user_id, $scope = null, $includeRefreshToken = true)
{
  $token = array(
        "access_token" => $this->generateAccessToken(),
        "expires_in" => $this->config['access_lifetime'],
        "token_type" => $this->config['token_type'],
        "scope" => $scope,
        "user" => $user_id[1] //NOTE: I added new user field and passed second index of array which is user node
    );

//NOTE: Here I passed $user_id[0] since $user_id is array hence I am using its 0 index here which has id
$this->tokenStorage->setAccessToken($token["access_token"], $client_id, $user_id[0], $this->config['access_lifetime'] ? time() + $this->config['access_lifetime'] : null, $scope);

  if ($includeRefreshToken && $this->refreshStorage) {
        $token["refresh_token"] = $this->generateRefreshToken();
        $expires = 0;
        if ($this->config['refresh_token_lifetime'] > 0) {
            $expires = time() + $this->config['refresh_token_lifetime'];
        }
        //NOTE: Same goes here passing $user_id[0]
        $this->refreshStorage->setRefreshToken($token['refresh_token'], $client_id, $user_id[0], $expires, $scope);
    }

  return $token; 

}

問題は、 composerを実行したときに bshaffer コア ファイルを変更したため、デフォルトのコードが上書きされ、composer を実行した後に毎回同じファイルを変更する必要があることです。componentこの calss/method をオーバーライドし、composer の実行後に同じように変更を加えた場合、適切な回避策が必要になる場合があります。

4

1 に答える 1

3

vendorそのような変更は次のコンポーザーの更新で上書きされるため、フォルダーの下にあるものは何も変更しないでください。

私が見る限り、それを構成するオプションはありません。それを難し​​くしているのは、それが拡張機能自体ではなく、拡張機能の依存ライブラリの問題であるという事実です。最初に、それを構成する方法を見つけるか、そのような変更を加える必要のない回避策を追加してみてください。できない場合、可能なオプションは次のとおりです。

1)イシュー/プル リクエストを作成し、変更が に追加されるのを待ちますbshaffer/oauth2-server-phpFilsh/yii2-oauth2-serverの新しいバージョンに更新できるように、正しい依存関係があることを確認してくださいbshaffer/oauth2-server-php(この場合、おそらくもう 1 つのイシュー / プル リクエストがFilsh/yii2-oauth2-server必要になります)。これにはかなり長い時間がかかる場合があります。

2)両方のライブラリのフォークを作成し、必要な変更を加えて代わりに使用します。composer.jsonPackagist に公開したくない場合は、リポジトリ セクションを使用できます。詳しくはComposer の公式ドキュメントを参照してください。

3)両方の拡張機能をプロジェクト コードにコピーし、バージョン管理下に置き、それらを変更して、vendorフォルダー内のものの代わりに使用します。

4)モンキーパッチを追加します。この機能は PHP でネイティブにサポートされていないため、そのような機能を提供する拡張機能 ( antecedent/patchwork ) を使用できます。

この場合、このメソッドを独自のメソッドに置き換えることができます。

公式ドキュメントの例に加えて、私も役立つ記事を見つけて、クラスの例を示しました。あなたの場合、それはより簡単で、次のようになります:

replace(\OAuth2\ResponseType:AccessToken:class. '::createAccessToken', function ($client_id, $user_id, $scope = null, $includeRefreshToken = true) {
    // Redefine method behavior as you want here
});

オプション1は時間がかかる可能性があり、Issue またはプル リクエストが拒否される可能性が常にあります。オプション23では、更新の可能性が失われます。

もし、あんたが:

  • そのような変更を加える必要なしに、それを構成する方法または回避策を見つけることができません。

  • これが緊急に必要です。

  • 一般的な機能ではなく、プロジェクト固有の機能のように見えます。

オプション4を使用してください。この場合、おそらくこれが最適です。

アップデート:

Yii2 組み込み機能を使用した別のオプションを次に示します。

5) Yii::$classMap()を使用して、クラスをカスタムのものに置き換えることができます。テストしたところ、拡張クラスでうまく機能します。

フォルダにコピーvendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseType/AccessToken.phpして貼り付けcommon/componentsます。メソッドcreateAccessTokenを変更しますが、名前空間を変更しないでください (そうしないと、Class not foundエラーが発生します)。

アプリケーションのブートストラップ中にクラス マップを使用してクラスを切り替えます。

Yii::$classMap['OAuth2\ResponseType\AccessToken'] = '@common/components/AccessToken.php';

index.phpアプリケーションが初期化されて実行される直前に配置できます。

$application = new yii\web\Application($config);
$application->run();

ただし、実装する別のブートストラップ コンポーネントを作成しBootstrapInterface、それをアプリケーション構成に含めることをお勧めします。

OAuth2\ResponseType\AccessTokenカスタムクラスを参照するときに使用されます。欠点は、拡張クラスから拡張して 1 つのメソッドだけをオーバーライドできないことですが、それは元の名前空間を保持する必要があるためです。

この関連する SO answerを確認してください。

于 2016-10-25T12:23:20.260 に答える