Posted at

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


概要

タスク管理ツール・TrelloのAPI認証ではOAuth1.0を使用しています。Risan\OAuth1というPHPのライブラリを使用して、認証を実装してみました。


前提

下記の実装サンプルはSlim3の使用を前提としています。Slim3の詳細については、

@Syo_prさんのPHP軽量FrameworkのSlim3をご参考ください。また、ライブラリのインストール方法や元にした実装サンプルは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;
}
}