2017/12/19
PHPとJIRA REST APIでユーザー認証してみよう大野 智之Tomoyuki Ohno
このエントリーは、 Atlassian(JIRA , Confluence, Trello, Bitbucket)のTips Advent Calendar 2017 – Qiitaの19日目です
はじめまして、リックソフトの大野です。
Webベースの業務システムのほとんどでは、システムごと認証画面が用意されており、各ユーザーは自身に割り当てられた認証情報(ユーザー名・パスワード)でログインしますが、システムが増えるとシステムの数に比例して認証情報も増え、認証情報の管理が煩雑となる場合があります。例えば、定期的なパスワード変更が長時間要することによる業務の停滞、パスワード使いまわしや脆弱なパスワードによるセキュリティリスクなど、認証情報の増加は様々な弊害を生む原因となります。
認証情報の管理は、情報システム管理者にとってもエンドユーザーにとっても、悩みのタネであろうと思います。
せめて自社開発の社内システムくらいは認証情報を共通化して管理を楽にできれば・・・しかしコストをかけずできるだけ手軽に行いたい(ディレクトリサーバやIDaaS等を用意せずに簡単な方法で行いたい)、JIRAはある(!)、そのような方に、今回はJIRA REST APIを用いた認証方法をご紹介いたします。
JIRA REST APIは、JIRAに実装されているREST APIです。
認証をはじめ、検索および一覧・詳細出力、課題作成・編集、課題削除など、普段JIRAへログインして手作業で行っている操作をAPIから行うことが出来ます。
JIRA REST APIの利用方法は、Atlassian が公開する以下のページに記載されています。
JIRA REST APIによる認証方法として、次の方法があります。
実装難易度は容易ですが、都度ユーザー名とパスワードをサーバへ送信する必要があります。
ユーザー名とパスワードはログイン時のみ必要となります。
ログイン後は戻り値として返されたJIRAのセッションID(JSESSIONID)を用いてセッション状態を保持することが出来ます。
今回はユーザー認証を行うことが目的であるため、この認証方法は検討外となります。
JIRA REST APIを利用したログインは、次のようなコードを実行することで行うことができます。
成功時に、JIRAのセッションID(JSESSIONID)をセッションにセットします。
※ $url, $username, $password および出力部分(var_dumpの部分)は、適宜変更します。
<?php // セッション開始 session_start(); // 配列を初期化 $result = [ 'result' => false, 'code' => 0, 'values' => [], ]; // JIRA REST APIのURL $url = 'https://www.example/jira/rest/auth/1/session'; $username = 'hogeuser'; $password = 'hogepass'; // POSTデータのセット $postData = [ 'username' => $username, 'password' => $password, ]; // cURLの初期化 $curl = curl_init(); // cURLの設定 curl_setopt($curl, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', ]); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($postData)); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // cURLの実行 $res = curl_exec($curl); // HTTPステータスコードの取得 $result['code'] = (int)curl_getinfo($curl, CURLINFO_HTTP_CODE); // cURLのクローズ curl_close($curl); // 成功時の結果代入(HTTPステータスが200(OK)の場合) if ($result['code'] === 200) { $result['values'] = json_decode($res, true); $result['result'] = true; // JIRAのセッションIDをsessionにセットする $_SESSION['JSESSIONID'] = $result['values']['session']['value']; } // 結果を出力 var_dump($result);
上記コードを実行すると、次のような結果が返ります。
HTTPステータスコードとして200が返り、JIRAの「JSESSIONID」が戻り値として返ります。
array(4) { ["result"]=> bool(true) ["code"]=> int(200) ["value"]=> array(0) { } ["values"]=> array(2) { ["session"]=> array(2) { ["name"]=> string(10) "JSESSIONID" ["value"]=> string(32) "324E7775065C2DFB5045501D6E5F0000" } ["loginInfo"]=> array(4) { ["failedLoginCount"]=> int(66) ["loginCount"]=> int(665) ["lastFailedLoginTime"]=> string(28) "2017-12-08T18:32:51.133+0900" ["previousLoginTime"]=> string(28) "2017-12-18T14:54:36.502+0900" } } }
HTTPステータスコードは、200以外が返ります。この状態の場合、認証に失敗しています。
array(3) { ["result"]=> bool(false) ["code"]=> int(401) ["value"]=> array(0) { } }
ユーザー情報の取得や、JIRAからの課題情報取得等を行いたい場合は、次のようなコードを実行することで結果を取得することが出来ます。
ログイン時にセットした「JSESSIONID」をcURL実行時にセットすることで、再認証(ユーザー名、パスワードを再入力・再送信)することなく結果を取得することが出来ます。
<?php // セッション開始 session_start(); // 配列を初期化 $result = [ 'result' => false, 'code' => 0, 'values' => [], ]; // JIRA REST APIのURL $url = 'https://www.ricksoft.jp/helpdesk/rest/api/2/user?key=hoge.taro'; // セッションにJESSSIONIDが存在しない場合は、falseを返す if (! isset($_SESSION['JSESSIONID'])) { return $result; } // セッションより、認証時に取得したJESSSIONIDを取得 $jSessionId = $_SESSION['JSESSIONID']; $cookie = 'JSESSIONID=' . $_SESSION['JSESSIONID']; // cURLの初期化 $curl = curl_init(); // cURLの設定 curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($curl, CURLOPT_COOKIEFILE, ''); curl_setopt($curl, CURLOPT_HTTPHEADER, ['Cookie: ' . $cookie]); // cURLの実行 $res = curl_exec($curl); // HTTPステータスコードの取得 $result['code'] = (int)curl_getinfo($curl, CURLINFO_HTTP_CODE); // cURLのクローズ curl_close($curl); // 成功時の結果代入(HTTPステータスが200(OK)の場合) if ($result['code'] === 200) { $result['values'] = json_decode($res, true); $result['result'] = true; } var_dump($result);
上記コードを実行すると、次のような結果が返ります。
HTTPステータスコードとして200が返り、結果が出力されます。
array(4) { ["result"]=> bool(true) ["code"]=> int(200) ["value"]=> array(0) { } ["values"]=> array(11) { ["self"]=> string(71) "https://www.example/jira/rest/api/2/user?username=hoge.taro" ["key"]=> string(13) "ohno.tomoyuki" ["name"]=> string(13) "ohno.tomoyuki" ["avatarUrls"]=> array(4) { ["48x48"]=> string(65) "https://www.example/jira/secure/useravatar?avatarId=10122" ["24x24"]=> string(76) "https://www.example/jira/secure/useravatar?size=small&avatarId=10122" ["16x16"]=> string(77) "https://www.example/jira/secure/useravatar?size=xsmall&avatarId=10122" ["32x32"]=> string(77) "https://www.example/jira/secure/useravatar?size=medium&avatarId=10122" } ["displayName"]=> string(24) "ほげ たろう" ["active"]=> bool(true) ["timeZone"]=> string(10) "Asia/Tokyo" ["locale"]=> string(5) "ja_JP" ["groups"]=> array(2) { ["size"]=> int(16) ["items"]=> array(0) { } } ["applicationRoles"]=> array(2) { ["size"]=> int(2) ["items"]=> array(0) { } } ["expand"]=> string(23) "groups,applicationRoles" } }
HTTPステータスコードは、200以外が返ります。例えば、以下(HTTPステータスコードが401)の場合、「JSESSIONID」が有効期限切れであるか、正しくない可能性があります。
array(3) { ["result"]=> bool(false) ["code"]=> int(401) ["value"]=> array(0) { } }
ログアウトの際は、次のコードを実行します。
<?php // セッション開始 session_start(); // 配列を初期化 $result = [ 'result' => false, 'code' => 0, 'value' => [], ]; // JIRA REST APIのURL $url = 'https://www.example/jira/rest/auth/1/session'; // セッションにJESSSIONIDが存在しない場合は、falseを返す if (! isset($_SESSION['JSESSIONID'])) { return $result; } // セッションより、認証時に取得したJESSSIONIDを取得 $jSessionId = $_SESSION['JSESSIONID']; $cookie = 'JSESSIONID=' . $_SESSION['JSESSIONID']; // cURLの初期化 $curl = curl_init(); // cURLの設定 curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE"); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($curl, CURLOPT_COOKIEFILE, ''); curl_setopt($curl, CURLOPT_HTTPHEADER, ['Cookie: ' . $cookie]); // cURLの実行 $res = curl_exec($curl); // HTTPステータスコードの取得 $result['code'] = (int)curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); // 成功時の結果代入(HTTPステータスが204の場合) if ($result['code'] === 204) { $result['values'] = json_decode($res, true); $result['result'] = true; } var_dump($result);
上記コードを実行すると、次のような結果が返ります。
HTTPステータスコードとして204が返ります。
HTTPステータスコードは、204以外が返ります。例えば、以下(HTTPステータスコードが401)の場合、「JSESSIONID」が有効期限切れであるか、正しくない可能性があります。
JIRA REST APIは、JIRAやAtlassian製品以外の認証サーバの代わりにも使えます。実装に必要なコードも見ていただいたとおりシンプルで、簡単に実装できます。
システムの認証もJIRAに任せられますので、認証やユーザー管理機能に係る工数を削減することができますし、運用面においてもユーザー管理やセキュリティにかかるコスト削減にも繋がります。
また、APIの利用に必要なプロトコルはHTTPで特別なプロトコルを必要としないため、JIRAが動作していてログインして利用可能な状態であれば、APIもすぐに使い始められます。
このような使い方もあるということで、参考としていただけますと幸いです。
アトラシアン社ではサポート範囲外となっているサードパーティ製のアドオンをリックソフトのRS標準サポートではサポートします。
リックソフトのRS標準サポートは開発元が提供するサポート以上の価値があります。
ツールを導入しただけでは成功とはいえません。利用者が効果を感じていただくことが大切です。独自で制作した各種ガイドブックはツール活用を促進します。
リックソフトからライセンス購入を頂いたお客様にはガイドブックを無料進呈いたします。
ツール操作の研修だけでなく「ウォータフォール型開発」「アジャイル型開発」のシミュレーション研修も提供。
日本随一の生産性向上にも効果のある研修サービスです。
リックソフトからライセンス購入を頂いたお客様には無料招待や割引特典がございます。