うちの社内向けサーバでWindowsユーザー名を得るためにPHPで統合Windows認証を模擬しています。そうすると毎回、レスポンスコード401の接続を2度経てからの接続となります。XHR (XMLHttpRequest)でもそうなるのでこれがどうもムダに思えて、最初の1回だけNTLMでユーザー名を取得して$_SESSIONに保管、あとは認証を省略しようとすると、IEとChromium版じゃない旧のEdgeでXHRからPOSTしたときにPOSTデータが空になる問題がありました。これが毎回ならわかるのですが、続けて接続すると問題なかったりします。どちらかというと問題が起こるほうがまれです。すべての接続で認証を有効に戻すとこの問題は起こらず、Chromeでは元から問題ありません。
調べてみるとこちらの問題のようで、JavaScriptで
document.execCommand('ClearAuthenticationCache', 'false');
を実行せよとか、asyncでの接続を同期にするとかありますが、試しても解決しませんでした。またこの命令は廃止ですし、同期接続もChromeとかで警告が出るので非同期のままでいたいところです。
他にも接続に100ms待てとかありますが、結局このページの最初の回答でレスポンス307で再度接続するようにとのアドバイスを試すと問題が解決できました。具体的には以下のようなコードをPOSTで呼び出しされるスクリプトの先頭に付加した感じです。
if (empty($_POST)) {
header('HTTP/1.1 307 Temporary Redirect');
header('Location: ./' . basename(__FILE__));
}
これでIEでも最初のPOSTで307が返ってすぐに正規の応答になることを確認しました。
社内向けサーバですので今までのようにXHRを含むすべての接続が401を2回後、NTLMで認証してでもいいんですが、ネットワークのトラフィックが気になる場合で認証を一部省略すると手間がかかるという話題でした。