【PHP】ある特定のAPIへリクエストすると勝手にリダイレクトされる
結論
リダイレクト時のステータスコードは 301
ではなく 302
を使う!
※もしくは明示的に指定しなければデフォルトで302になる
前提
一般ユーザーAでログインしているときに /user
へリクエストすると、制限された情報を返すAPIがある。
一方、Adminユーザーでログインしているときに /user
へリクエストすると、API側でAdminであれば /admin/user
へリダイレクトさせる処理があった。
このときにリダイレクト処理を下記のようにしてしまっていた。
<?php if ($user_id === ADMIN_USER_ID) { header("Location: /admin/user", true, 301); exit; }
再現手順
- Adminユーザーでログインして
/user
へリクエストすると、API側で/admin/user
にリダイレクトされる。(想定された挙動) - Adminユーザーからログアウト
- 一般ユーザーAでログイン
/user
へリクエストすると、/admin/user
へなぜかリダイレクトされる。/admin/user
自体はAdminユーザーでないと認可していないので、 ステータスコードは403
で返ってくる。(想定されていない挙動)- 想定されたレスポンスが返ってこないのでエラーが出る。
原因
301
でリダイレクトさせるとブラウザ側でキャッシュしてしまうことが原因っぽい。
ちゃんとドキュメントに書いてあった。
A quick way to make redirects permanent or temporary is to make use of the $http_response_code parameter in header().
<?php // 301 Moved Permanently header("Location: /foo.php",TRUE,301); // 302 Found header("Location: /foo.php",TRUE,302); header("Location: /foo.php"); // 303 See Other header("Location: /foo.php",TRUE,303); // 307 Temporary Redirect header("Location: /foo.php",TRUE,307); ?>
The HTTP status code changes the way browsers and robots handle redirects, so if you are using header(Location:) it's a good idea to set the status code at the same time. Browsers typically re-request a 307 page every time, cache a 302 page for the session, and cache a 301 page for longer, or even indefinitely. Search engines typically transfer "page rank" to the new location for 301 redirects, but not for 302, 303 or 307. If the status code is not specified, header('Location:') defaults to 302.