apiサーバ、はじめの一歩【id_tokenの検証】

昨日はIDトークンを取得するところまでやりました。

今日はAPIサーバを立てて、そこに取得したIDトークンをbearer認証的に投げて
IDトークンの有効性をチェックして結果をJSONで返すAPIを作ろうと思います。

=== 今日の目標 ===

ブラウザからajaxでAPIサーバにベアラ認証でIDトークンを投げる
APIサーバでIDトークンを検証する

=== 構成 ===

Webアプリケーションサーバ
hoshidora.game.chiekoubou(ドメイン)
┣index.php <= LineLoginページへ遷移を促すページ。多分今回は出てこない ┗getToken.php <= LineLoginからリダイレクトされてくるページ。ここからAPIをJsでたたく。 APIサーバ api.hoshidora.game.chiekoubou(ドメイン) ┗checkIdToken.php(TokenId検証用APIのエンドポイント) とします。

1. IDトークンの検証機能を作ってみる

検証機能作成のために
まず、checkIdToken.php に さっき取得したTokenIDを固定で入力しときましょう。

checkIdToken.php

'invalit_grant',
			'error_description'=>'IDトークンの照合に失敗しました。',

		);}elseif($payload->iss == LINE_LOGIN_ISS){$err =array(
			'error'=>'invalit_grant',
			'error_description'=>'LINE LOGINで生成されたトークンではありません',

		);}elseif($payload->aud == LINE_LOGIN_CLIENT_ID){$err =array(
			'error'=>'invalit_grant',
			'error_description'=>'チャネルIDが一致しません',

		);}elseif($payload->nonce == $nonce){$err =array(
			'error'=>'invalit_grant',
			'error_description'=>'nonceが一致しません',

		);}elseif($payload->exp < time()){$err =array(
			'error'=>'invalit_grant',
			'error_description'=>'IDトークンの有効期限が切れています',
		);}
		
		if($err){return array('status'=>'error','data'=>$err);} 
		return array('status'=>'success','data'=>array('lineId'=>$payload->sub));

	}
	
	//検証機能テスト用にIdトークンを直打ち
	var $idToken = '【以前取得したIDトークン】';
	var $nonce = '【上記のIDトークンを取得するときに生成して一緒に投げたnonce】';

	// ベアラ認証ヘッダで飛んできたTokenIdをキャッチ
	//var $idToken = explode(' ',getallheaders()['Authorization'])[1];
	// パラメータで飛んできたnonceをキャッチ
	//var $nonce = $_GET['nonce'];

	
	print_r( certIdToken_line($idToken,$nonce));


status が success となれば検証が無事成功できました、という事です。

ここで大ハマりしたポイントが secret の照合でした。

トークンの二つ目までのピリオドまでをチャネルsecretを鍵としてsha256でハッシュ化したものと
base64urlでデコードしたIDトークンのsecret部が同じになるかどうか
という検証なんですが

まず base64url を普通base64_decode で複合させてたのが問題点その1でした。
よく読んだらちゃんと書いてあるじゃんね。ちゃんと見ろ、僕!

念のため base64urlについて説明しますが、
これは通常のbase64で使用される文字に少し手を加えられてるバージョンで
具体的にいうと + を – に / を _ に置き換えてあります。
なので phpの関数である base64_decode() で複合するなら
-を+ に _を/ に置換してからぶっ込んでやればいいという事ですね。

また、復号後のsecret部がバイナリ値だったので
bin2hexしてあげないといけないのもちょっとハマりましたね。

そこまでできれば後は大して難しくないと思います。
検証内容は ペイロードに含まれている
生成元の確認(この場合はLineLogin),チャネルID,IDトークンの有効期間の確認
それから、シグネチャ部の称号です。
シグネチャ部の称号はちょっとめんどくさいかもですね。
上の
if($signature != $signatureTest){ $err =array(
ここの部分ですね。
ソースの上から順に追って行けば何をやってるかはわかるはず!

実際にはIDトークンはbearer認証として扱い、GETパラメータでnonceを受け取る予定なので、
飛んできたそれらを受け取るための記述が
// ベアラ認証ヘッダで飛んできたTokenIdをキャッチ
//var $idToken = explode(‘ ‘,getallheaders()[‘Authorization’])[1];
// パラメータで飛んできたnonceをキャッチ
//var $nonce = $_GET[‘nonce’];ここね。

検証機能の検証が大丈夫そうなら直打ち部をコメントアウトして
こっちのコメントアウトを外してください。

2. ブラウザからajaxでベアラ認証でアクセスさせてみる

そんじゃブラウザからapiサーバにIDトークンを投げるぞ!

そもそもベアラ認証ってなんなのさ
というところから始まりました。

超簡単に言うと
http通信のヘッダに
Authorization: Bearer
とつけて、IdTokenをもって認証する仕組み、、、らしい。

まぁ、とりあえず、やってみようか!



	
	
	

通信結果

ものすごい大ハマりをしたので、先に書いておきます。

僕はFirefoxを使ってるのですが、どうやらこいつはヘッダにAuthorizationがあると
先に該当URLにOPTIONSでアクセスしてヘッダをもらい、
そこにCORS系のヘッダがあるかを確認してからGETなりPOSTなりするという仕様らしいです。

実装するときにslim3で実装していて
GETの対応は書いていたもののOPTIONSの対応がかけていなかったので
ブラウザさんにXSRFかもしれないからアクセスさせてやらん、と怒られてたわけですな。

また、OptionsとGetで同じ処理とかにしちゃうと、同じ処理を2回やるってことになっちゃうので
optionsはCORSヘッダ処理用と割り切って、何もしない様にしないといけないっぽいです。
slim3のルーティングだとその辺もそこそこ簡単にかけますね。

ただ、今回は検証用なので適当です。
とりあえずAPIサーバにリクエスト投げて検証した結果が返ってくればいいや、的な。

これで通信結果の下にlineIDが表示されればOKです。

上手くできたかしら?

今回はうまくいかないことが多くて非常に疲れました!

今日はこの辺で!

t

←よかったらクリックお願いします。

kataware の紹介

二児の父、職業SE、やりたいことはゲームと歌とアプリ作ったりサーバいじったり娘の服を作ったり色々あり過ぎて時間が足りなさ過ぎて病みそうだから娘に癒してもらってる。
カテゴリー: php, SE備忘録, ソシャゲ支援ツール開発記   パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です