TAMINIF’s blog

京都在住のWebエンジニア。iOSアプリもやってます。勉強会にも参加してます。最近はマネージャー色強め

WordPressの管理画面にログインできない問題の原因がDBだった

WordPressの管理画面にログインできない問題が発生し、解決まで完了したのでブログに書く。正確に事象を説明するとログイン画面は表示されて、正しいログイン情報を入力してログインボタンを押した場合にリダイレクトが発生しログイン画面が表示されるという無限ループが起きた。
調べても出てこないケースの問題だったのと、なかなかに怒りが発生したのでそれをモチベーションに今書いている。

動作環境

WordPress4.7(バージョン関係なし)
AWS EC2
MariaDB

TL;DR

ディスク使用量が100%になるとDBに書き込みできないので、ディスクに空きを作る。

どう調査したか

まずは画面で調査を行い、何が起きているかを確認したところ、ログインボタンを押した時に
POST wp-login.php 302->GET wp-admin/admin.php 302->GET wp-login.php 200
とリダイレクトしていることを確認した。

wp-admin/admin.phpのどこでリダイレクトしているか調査したところ、auth_redirect()wp_validate_auth_cookie()でfalse判定になっていることでログイン状態の判定がされないことがわかったので、なぜfalse判定となるのかを調査。

https://github.com/WordPress/WordPress/blob/master/wp-includes/pluggable.php#L1044

ここからが長かった。
$manager->verify( $token )がfalseになっていることはわかったが、これがなぜfalseになるのかがわからない。

https://github.com/WordPress/WordPress/blob/master/wp-includes/pluggable.php#L675

このセッションがどこに保存されているか、このセッションがどういう情報が入っているのかも知らない状態から調べ始めたのでこれが何もわからない。
ようやくwp_usermetaテーブルにセッション情報が入っていることまで確認したが、もともと入っているデータがどうなっているのかもわからない。
そもそもいつ更新されるかもわからなかった。
これを一つずつ調べるのにすごい時間がかかった。

wp_usermetaテーブルが更新されない

$manager->verify( $token )はwp_usermetaに入っているsession_tokenから、Cookieに格納されているトークンを使って一致するキーから情報を取得するのだが、ここにトークンと一致する情報が存在しないからログイン判定がなされない。 ここに一致する情報がないと絶対に解決しないことがわかったので、どうやって格納しているかを調査する方向に転換した。

調査をしたところ、ログイン成功時にトークンを発行し、それをセッション(DB)とCookieに格納していた。

https://github.com/WordPress/WordPress/blob/master/wp-includes/pluggable.php#L877

Cookieが格納されていることは開発者ツールで確認している。なのでセッションに格納されないことが原因だと判明。

https://github.com/WordPress/WordPress/blob/master/wp-includes/class-wp-session-tokens.php#L151

トークンは生成時にセッションに格納している。

https://github.com/WordPress/WordPress/blob/master/wp-includes/class-wp-user-meta-session-tokens.php#L98

この処理でセッション(DB)に格納している。
update_user_metaを調査。

https://github.com/WordPress/WordPress/blob/8f5d82df7b0b5b2fbaed8ca4c2ad49876f8175df/wp-includes/meta.php#L268

DBにQueryを実行し結果を返している。まさか。
update_user_metaの実行結果を出力してみる。
falseが返ってきた。

DBの更新処理が失敗している!!!

原因が判明。あとはなぜDBの更新が失敗しているかを調査し、実際にDBに入って更新処理を実行してみたところ同じように失敗 Disk Full 〜と出力されたので、DBを抜けてdf -hを実行、100%となっていることを確認。。。

解決方法

容量を圧迫しているファイルを探し、今回はログファイルを圧縮することでログインできるようになった。

怒りポイント

ソースコードを読むのが辛い

とにかくソースコードを読むのが辛い。ログイン処理とかどこで書き込みしているのかわからない。

https://github.com/WordPress/WordPress/blob/master/wp-login.php

そして、一つの関数の内容が多すぎる。どうみても一つの責務だけを担当していない。
関数のコードが大きいということは、関数内の何で問題になっているかから調査しないといけないので、その労力がすごく大きい。

DB処理失敗時に何もしない

今回の原因となったDBの更新処理について、失敗した場合にfalseを返すだけなので、ログも残らないし処理も終了しない。
DBの更新に失敗ってWordPressだと致命的だと思うので、せめて例外を投げて処理を終了してほしい。
解決したあと、そりゃわからないわと思ってしまった。

まとめ

多分ここで愚痴るよりPR投げた方が早いが、多分WordPressは大きくなりすぎてしまったんだと思う。
自分もこのブログにWordPressの記事を書くことになるとは思わなかった。
もう少し平和に過ごしたい。