ツイキャスAPIがAPIV2になり、認証が必要になりました。
そろそろ対応を検討しようと思い、認証部分を実装してみました。
開発API - ツイキャス
http://twitcasting.tv/indexapi.php
- CreateApp
============
ツイキャスにログインし、次のURLにアクセスします。
My Apps
https://ssl.twitcasting.tv/developer.php
[Create New App]ボタンをクリックし、アプリの情報を設定します。
ここで、コールバックURLが必須になっており、WindowsアプリやWebアプリを作る場合はWebサーバーを立てる必要があります。
- APIの呼び出し
================
次のライブラリを使用しました。
TwitCastingOAuth
https://github.com/shucream0117/twitcasting-oauth
2.1. 認証URLへリダイレクト
まず、confirmページにアクセスさせます。
このページでは認証URLを取得し、リダイレクトしています。
認証URLの取得にはAuthCodeGrant->getConfirmPageUrl()を使います。
/**
* 確認ページリダイレクト
*/
public function confirm() {
// CSRFトークン
$csrfToken = md5(uniqid(rand(),1));
// AuthGrandの生成
$grant = new AuthCodeGrant(ClientId, ClientSecret, CallbackUrl);
// 認証ページURLの取得
$url = $grant->getConfirmPageUrl($csrfToken);
// セッションデータのセット
$this->session->set(CsrfTokenKey, $csrfToken);
// リダイレクト
$this->response->redirect($url);
}
2.2. 連携アプリを許可
リダイレクト先では[連携アプリの許可]か[キャンセル]が選べるようになっています。
2.3. アクセストークンの取得
連携アプリの許可ページでアクションを起こすとコールバックURLにリダイレクトされます。
連携アプリが許可された場合は、コールバックURLにcodeパラメータが付与されます。
このcodeパラメータを使えばアクセストークンを取得できます。
アクセストークンの取得にはAuthCodeGrant->requestAccessToken()を使います。
なお、キャンセルされた場合はresultパラメータがdeniedになります。
/*
* コールバック
*/
public function callback() {
$req = $this->request;
$req_base = $req->getBasePath();
$this->view->req_base = $req_base;
$req_base_url = $req->getBaseUrl();
$this->view->req_base_url = $req_base_url;
// GETパラメータ
$query = $req->getQuery();
if (isset($query['result'])) {
$result = $query['result'];
if ($result == 'denied') {
// 認証がキャンセルされた
$this->_authFailed();
return;
}
}
// CSRFトークンのチェックをここで実装
// あとで
$code = $query['code'];
// AuthGrandの生成
$grant = new AuthCodeGrant(ClientId, ClientSecret, CallbackUrl);
// アクセストークンのリクエスト
$accessToken = $grant->requestAccessToken($code, new AppExecutor(ClientId, ClientSecret));
$accessTokenStr = $accessToken->getAccessToken();
$pageData = array(
'confirmed' => 1,
'accessToken' => $accessTokenStr,
);
$this->view->pageData = $pageData;
}
- 全ソースリスト
===============
<?php
require_once 'vendor/autoload.php'; // TwitCastingOAuth
use Shucream0117\TwitCastingOAuth\GrantFlow\AuthCodeGrant;
use Shucream0117\TwitCastingOAuth\ApiExecutor\AppExecutor;
/**
* 定数
*/
const ClientId = 'ClientId';
const ClientSecret = 'ClientSecret';
const OwnerId = 'OwnserId';
const CallbackUrl = 'http://example.com/twcaschatlisten/callback';
const CsrfTokenKey = 'csrfToken';
/**
* TwcasChatListenコントローラー
*/
class TwcasChatListenController extends Controller {
/**
* プリプロセス
*/
public function preProcess() {
$this->view->setLayout('default_twcaschatlisten');
}
/**
* 確認ページリダイレクト
*/
public function confirm() {
// CSRFトークン
$csrfToken = uniqid();
// AuthGrandの生成
$grant = new AuthCodeGrant(ClientId, ClientSecret, CallbackUrl);
// 認証ページURLの取得
$url = $grant->getConfirmPageUrl($csrfToken);
// セッションデータのセット
$this->session->set(CsrfTokenKey, $csrfToken);
// リダイレクト
$this->response->redirect($url);
}
/*
* コールバック
*/
public function callback() {
$req = $this->request;
$req_base = $req->getBasePath();
$this->view->req_base = $req_base;
$req_base_url = $req->getBaseUrl();
$this->view->req_base_url = $req_base_url;
// GETパラメータ
$query = $req->getQuery();
if (isset($query['result'])) {
$result = $query['result'];
if ($result == 'denied') {
// 認証がキャンセルされた
$this->_authFailed();
return;
}
}
// セッションデータの取得
$csrfTokenSaved = $this->session->get(CsrfTokenKey);
if (!$csrfTokenSaved) {
//echo 'session has been expired<br>';
$this->_authFailed();
return;
}
if (!isset($query['state'])) {
//echo 'csrf token is invalid<br>';
$this->_authFailed();
return;
}
$state = $query['state'];
if ($state != $csrfTokenSaved) {
//echo 'csrf token is invalid<br>';
$this->_authFailed();
return;
}
$code = $query['code'];
// AuthGrandの生成
$grant = new AuthCodeGrant(ClientId, ClientSecret, CallbackUrl);
// アクセストークンのリクエスト
$accessToken = $grant->requestAccessToken($code, new AppExecutor(ClientId, ClientSecret));
$accessTokenStr = $accessToken->getAccessToken();
$pageData = array(
'confirmed' => 1,
'accessToken' => htmlspecialchars($accessTokenStr),
);
$this->view->pageData = $pageData;
}
/**
* 認証失敗
*/
private function _authFailed() {
$pageData = array(
'confirmed' => 0,
'accessToken' => '',
);
$this->view->pageData = $pageData;
}
}