今年のQiita Advent Calendarに投稿予定です(CakePHPとDjango)。
いずれも12/20ですので、興味があればご覧ください。
さて、今回はCakePHPに関する記事です。
結論から言うと、PRがマージされましたというお話です。
背景
私は自作アプリのログイン・ログアウトにGoの外部API(これも自作したやつです)を使っており、 それぞれ以下のように処理しています。
ログイン
- アプリ:ユーザ・パスワードで認証APIをコール(POSTメソッド)
- API:処理成功時、ステータスコード
200
とアクセストークン返却 - アプリ:アクセストークンを利用してユーザ取得APIをコール(GETメソッド)
- API:処理成功時、ステータスコード
200
とユーザ情報を返却 - アプリ:取得したユーザ情報をセッションに格納してログイン成功
ログアウト
- アプリ:アクセストークンを利用して認証解除APIをコール(DELETEメソッド)
- API:処理成功時、ステータスコード
204
を返却
ある時、CakePHP3を使ったアプリで、正常にログアウトした場合でもエラーログが出ていることに気づきました。
2017-11-23 20:31:41 Error:
「エラーのくせに詳細が何も出力されないだと…」
という衝撃を隠しきれませんでしたが(笑)、一旦落ち着いて発生箇所を調査することに。
原因
use Cake\Http\Client;
public function logout($data, $headers, $assoc)
{
// 外部APIをコールして、認証解除を実施する
$http = new Client();
$response = $http->delete('http://api.example.com/logout', $data, $headers);
$body = $response->getBody();
// 処理成功時は 204 がセットされる
$this->response = $this->response->withStatus($response->getStatusCode());
// \Cake\Http\Client\Messsage には`200`~`202`の定義しかないため、
// \Cake\Http\Client\Responseのこのメソッドは`204`をOKとしていない
if ($response->isOk()) {
return json_decode($body, $assoc);
}
// 失敗
Log::error($body);
}
コメントに書いた通りなのですが、上記コードをもとに説明します。
- ログアウト時の処理2でステータスコード
204
が返ってくる isOk()
の対象でないためif文に入らない- レスポンスボディもないため、CakePHP側16行目
Log::error()
で出力する$body
も空
という流れで、何も情報が無いエラーログが出力されてしまっていたということです。
これだけなら「あえて204
をOKしてないのかな」とも思えたのですが。
// IntegrationTestCase.php
public function assertResponseOk($message = null)
{
if (empty($message)) {
$message = 'Status code is not between 200 and 204';
}
$this->_assertStatus(200, 204, $message); // 200 ~ 204 までOKとみなす
}
CakePHP3側の基底テストケースではまさかのOK対象内。
修正~PR
CakePHP側のコード修正・テストコードの修正および実施を行い、 それらのPRを出したところ、5時間ほどで無事マージされました。
ドキュメントは以前PRがマージされたのですが、コード側は初めてです。
「PRは内容に問題なければサクッとマージしてもらえるんだな」ということがわかりました。
とはいえ、IssueやPR作成時の説明にもあるように、注意する点もいくつかありますので、詳細は以下をご覧ください。
CakePHP コミュニティセンター
それでは、良いCakePHPライフを。