2016-09-13 1 views
0

シンプルなSymfony2プロジェクトを作成しました。従業員はログインしてニュースやその他のものをチェックできます。次に、社員が働いているかどうかを示す外部システムを統合したいと考えました。他のシステムを制御することはできませんが、必要な情報を取得できるようにWeb API(REST)が用意されています。Symfony2の外部Web APIからのアクセスとリフレッシュトークンをどこに格納するのですか?

このpost (stackoverflow)の回答のために、私は必要な情報を得るためにPHP HTTPクライアントとしてGuzzleBundleを使用することに決めました。

だから私は、ログインウェブAPIによって必要とされている:

$client = new GuzzleHttp\Client(); 
$req = $client->request("POST", "https://httpbin.org/login", ['body' => ['user' => 'user', 'pw' => 'pw']]); 
$response = json_decode($req->getBody()->getContents()); 

そして、私は$レスポンスから提供されたアクセストークンを使用:このように必要な情報を取得するには

{ 
    "success": true, 
    "content": [ 
    { 
     "accessToken": "x", 
     "accessTokenExpires": "date", 
     "refreshToken": "z", 
     "refreshTokenExpires": "date" 
    }] 
} 

を:

$reqPara  = ['body' =>["accessToken" => $at, "department" => $department, "location" =>$location]]; 

$req = $client->request("POST", "https://httpbin.org/employees/atwork", $reqPara); 
$response = json_decode($req->getBody()->getContents()); 

私が望むものを得ました:

{ 
    "success": true, 
    "content": [ 
    { 
     "employee": "a", 
     "status": "at work", 
    }, 
    { 
     "employee": "b", 
     "status": "not at work", 
    } 
    ] 
} 

もちろん、従業員が働いているかどうかを知りたいときはいつでもログインすることができますが、アクセストークンを使用することができればそれは無駄に思えます。しかし、再びアクセストークンが期限切れになると、新しいトークンを生成するためにリフレッシュトークンが必要ですが、これらのトークンをどこに保存して後で再利用するのですか?データベースや設定ファイルで?これは標準的な存在ですか?

答えて

0

Dmitry Malyshenko私が聞く必要があった答え。いくつかのファイルに

  • 店舗:有効なソリューションの

    例として - 「...それは完全にあなた次第それがキャッシュされますどのようにこのトークンは、コンフィギュレーションに保存されていない、キャッシュされなければならないことは明らかです」いくつかのキーと値のストレージ内だけでメモリ内のデータベース

  • 店で
  • ストア(あなたのクラスのプロパティとして )
  • 店(Redisの、 memcacheの)

私はCacheComponentを使用しましたが、現在Symfony 3.1では開発していないので、最も自然に感じ取ったデータベースに保存することにしました。最初に、mysqlデータベースにユーザ名、パスワード、トークンを含むテーブルを作成しました。次に、そのテーブル専用のサービスを作成しました。これは、この単純化されたコードのようになります。

class ExternalSiteService 
{ 
    public function getUsername() { 
     ... 
    } 

    public function getPassword() { 
     ... 
    } 

    public function getAccessToken() { 
     ... 
    } 

    public function setAccessToken($newAccessToken) { 
     ... 
    } 

    public function getRefreshToken() { 
     $query="SELECT " 
      . "eapi.refreshtoken " 
      . "FROM external_api eapi"; 
     $connection = $this->em->getConnection(); 
     $statement = $connection->prepare($query); 
     $statement->execute(); 
     $results = $statement->fetchAll(); 
     if ($results) { 
      return $results; 
     } 
     return false; 
    } 

    public function setRefreshToken($newRefreshToken) { 
     $query="UPDATE external_api " 
      . "SET refreshtoken = :new_refreshtoken " 
      . "WHERE id=1;"; 
     $connection = $this->em->getConnection(); 
     $statement = $connection->prepare($query); 
     $statement->bindValue('new_refreshtoken', $newRefreshToken); 
     $statement->execute(); 
    } 
} 

は、その後、私はアクセストークンではない有効な利用のリフレッシュトークンあれば言うコントローラにいくつかのロジックを作って、リフレッシュトークン有効でない場合は、新たなログイン試行を行います。コントローラー内のこのコードは、新しいトークンを取得する必要がある場合は、データベースにトークンも格納します。

$eapiService = $this->get('mybundle.service.externalapi'); 
    $reqPara  = ['body' =>["accessToken" => $at, "department" => $department, "location" =>$location]]; 

    $req = $client->request("POST", "https://httpbin.org/employees/atwork", $reqPara); 
    $response = json_decode($req->getBody()->getContents()); 

    if ($response->serverErrorMessage == "Invalid access token.") { 
     $req = $client->request('POST', "https://httpbin.org/getnewtokens", ['body' => ['refreshToken' => $refreshToken]]); 
     $response = json_decode($req->getBody()->getContents()); 

     if ($response->serverErrorMessage == "Invalid refresh token.") { 
      $req = $client->request('POST', 'https://httpbin.org/login', ['body' => ['user' => $user, 'pw' => $pw]]); 
      $response = json_decode($req->getBody()->getContents()); 
      foreach ($response->content as $contentItem) { 
       $eapiService->setAccessToken($contentItem->accessToken); 
       $eapiService->setRefreshToken($contentItem->refreshToken); 
      } 
     } else { 
      foreach ($response->content as $contentItem) { 
       $eapiService->setAccessToken($contentItem->accessToken); 
       $eapiService->setRefreshToken($contentItem->refreshToken); 
      } 
     } 
    } 
    return array('usersatwork' => $response); 

私はおそらくグズルから例外をキャッチするものを作るでしょう。

0

ストアparameters.yml

+0

ありがとうB.私はこのオプションのconfigsをparameters.ymlで知っていますが、ユーザー名とパスワードを保存すると、GuzzleBundleキャッシュトークンを意味するのでしょうか?それは私には分かりません。私はここで間違っているかもしれませんが、それらのトークンを使用することは "正しい"ようです。迅速なgoogle検索は、トークンを使用する際の安全性が高いことを示しています。 – iknownothing

1

内部のユーザ名とパスワードは設定に格納されていない、このトークンをキャッシュしなければならないことは明らかです。どのようにキャッシュされるのでしょうか?それはあなた次第であり、通常はアプリケーションの開始頻度、環境の設定方法などによって異なります。

これらはすべて、ファイルを保存する、データベースに保存する、クラスのプロパティとしてメモリに保存する、キー値ストレージ(redis、memcache)を格納するなどの有効なソリューションです。

Symfony 3.1を使用している場合は、これにはCacheComponentを使用することをおすすめします。

関連する問題