PHPのRisan\OAuth1を使用してOAuth認証を試してみた

## 概要
タスク管理ツール・[TrelloのAPI認証](https://developers.trello.com/page/authorization)ではOAuth1.0を使用しています。Risan\OAuth1というPHPのライブラリを使用して、認証を実装してみました。

## 前提
下記の実装サンプルはSlim3の使用を前提としています。Slim3の詳細については、
@Syo_prさんの[PHP軽量FrameworkのSlim3](https://qiita.com/Syo_pr/items/b55e18a8361b3ff882b5)をご参考ください。また、ライブラリのインストール方法や元にした実装サンプルは[Risan\OAuth1](https://github.com/risan/oauth1)にあります。

## 実装サンプル
OAuth認証用のクラスとControllerでクラス分けして実装しています。

### 認証用クラス

```TrelloApiUtil.php
<?php
namespace util;

use Risan\OAuth1\ProviderFactory;
use Risan\OAuth1\Credentials\TemporaryCredentials;
use Risan\OAuth1\Credentials\TokenCredentials;

require_once __DIR__ . ('/../constants/AuthenticationConstants.php');

class TrelloApiUtil
{
  // trello用のoauth1
  private static function getOauth1(){
    $oauth1 = ProviderFactory::trello([
      'client_credentials_identifier' => TRELLO_API_KEY,
      'client_credentials_secret' => TRELLO_SECRET,
      'callback_uri' => 'http://localhost:8000/auth_callback',
    ]);
    return $oauth1;
  }

  // 一時署名の取得
  public static function getRequestTemporaryCredentials(){
    return self::getOauth1()->requestTemporaryCredentials();
  }

  // 認証用URLの取得
  public static function getBuildAuthorizationUri(TemporaryCredentials $temporaryCredentials, String $app_name){
    return self::getOauth1()->buildAuthorizationUri($temporaryCredentials) . "&name=" . $app_name;
  }

  // tokenの取得
  public static function getRequestTokenCredentials(TemporaryCredentials $temporaryCredentials, String $oauth_token, String $oauth_verifier){
    return self::getOauth1()->requestTokenCredentials($temporaryCredentials, $oauth_token, $oauth_verifier);
  }

  // リクエストの送信
  public static function sendRequest(TokenCredentials $tokenCredentials, String $type, String $path){
    return self::getOauth1()->setTokenCredentials($tokenCredentials)->request($type, $path);
  }
}
```

### Controller
認証に成功したらログインユーザの情報を取得する処理にしています。

```LoginController.php
<?php
namespace controller;

require_once __DIR__ . ('/../util/TrelloApiUtil.php');

use Slim\Http\Request;
use Slim\Http\Response;
use util\TrelloApiUtil;

class LoginController
{
  public function login(Request $request, Response $response){
    // TemporaryCredentialの発行
    $temporaryCredentials = TrelloApiUtil::getRequestTemporaryCredentials();
    // セッションにTemporaryCredentialを入れる
    $_SESSION['temporary_credentials'] = serialize($temporaryCredentials);
    // 認証用のURLにアプリの名前を付与
    $authorizationUri = TrelloApiUtil::getBuildAuthorizationUri($temporaryCredentials ,"testApi");
    // trelloの認証サイトにリダイレクト
    header("Location: {$authorizationUri}");
    exit();
  }

  public function auth_callback(Request $request, Response $response){
    // セッションにすでにtokenが設定してある。
    if (isset($_SESSION['token_credentials'])) {
      $tokenCredentials = unserialize($_SESSION['token_credentials']);
      // 自ユーザー情報を取得
      $response = TrelloApiUtil::sendRequest($tokenCredentials, 'GET', 'members/me');
    // GETの引数でoauth_tokenとoauth_verifierがある
    } else if (isset($_GET['oauth_token']) && isset($_GET['oauth_verifier'])) {
      // TemporaryCredentialを取得してsessionから破棄
      $temporaryCredentials = unserialize($_SESSION['temporary_credentials']);
      unset($_SESSION['temporary_credentials']); 
      // tokenを作成しセッションへ格納
      $tokenCredentials = TrelloApiUtil::getRequestTokenCredentials($temporaryCredentials, $_GET['oauth_token'], $_GET['oauth_verifier']);
      $_SESSION['token_credentials'] = serialize($tokenCredentials);
      // 自ユーザー情報を取得
      $response = TrelloApiUtil::sendRequest($tokenCredentials, 'GET', 'members/me');
    // それ以外はエラー
    } else {
      $response = $response->withJson(["message" => "Authentication_NG"], 401);
    }
    header("Content-Type: application/json; charset=utf-8");
    return $response;
  }
}
```