一応確認しているのは watchOS 6.2, 7.0, 8.0 only ですが。
実は OAuth ログインの際、Apple Watch (watchOS 6.2 以降) でも唯一 WebKit ブラウザーを立ち上げて認証できるわけですが、なぜか ID, PW (& Onetime) を入れてもトップページに戻されるという不具合が発生しています。
現状調査し、サーバー側ではなく watchOS 固有の問題かもしれないと思い、SwiftUI の Blank Project を作り、iOS 向けに ASWebAuthenticationSession
を実行してみたのですが、iPhone では正常……
唯一、通信ログを見て気づいたところとして、指定の URL に対して、2 回リクエストしていることなんですよね。
1 回目は、Accept: */*
でリクエストされているのに対し、2 回目は、Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
でリクエストされているという。リクエスト発行時間は同じ時間なので、謎という。
一応、新しい iPhone プロジェクトをベースに watchOS のプロジェクトも作成し、同じコードを使ってみましたが、本アプリ実装と同じような状態を再現できたので、watchOS の ASWebAuthenticationSession
の不具合のようです。
ちなみに接続先は Mastodon で pawoo.net (2FA 有効), mastodon.social (2FA 無効) で同じような感じになったので、最初の 2 回リクエストが悪さをしているのかな? (セッション周りの不具合? 本来なら最初にリクエストされた方のセッションが無効化され、2 回目のセッションのみが有効なる挙動であればこういうことにはならなそうですが)
まだ watchOS 8.0 でしか確認できていないのと、他のサービスでは問題ないか、など、根本的原因を突き止められていない(あまりにも見る範囲がデカすぎるので、もし Mastodon 関連や OAuth 実装に詳しい方などの協力をいただければ少し作業が捗るかも)ため、続報までもう少しかかるかも。
どちらにせよ、watchOS の ASWebAuthenticationSession
の修正、Mastodon の first request の無効化、second request を正しく受理できるようにする、など複合的要因によって発生している可能性が高く、一つ一つ紐解かないといけない現象なので、調査に時間がかかりそうです。
追記: watchOS 7.0 では、1 回目と 2 回目のリクエストが逆(ただ同時に発行されているため、あんまり関係ないと思いますが)になっており、同じような状況を再現できました(手書き入力なのでだるいですが)。
一応、先行公開でブログに掲載しておきます。
11/19 追記
どうやら、正常に動いているリクエストと、そうでないリクエスト (Apple Watch) を比較していると、クッキーの値が正しくセットされていないケースがある模様。
おそらく、サーバーから 302 レスポンスが帰ってきている場合、Set-Cookie
を無視する感じがする。この例だと、_mkra_stck
, _session_id
, remember_user_token
が /auth/sign_in
に対してリクエストしたレスポンスとして設定されているが、完全に無視して次のリクエスト投げているから正常にログインが完了しないっぽい (_mastodon_session
も新しいものが送られてきているが更新されていない)。
watchOS での WebKit は何かと不具合ありそうで厄介ですね。なぜこのような挙動になるのかは謎ですが、少なくともクッキー周りが悪影響を及ぼしている可能性は高そうです。buggy な動作として Apple に投げるべきかもしれませんがどこに投げればいいのでしょうか?
// 不具合が治るまでこの機能はお蔵入りになりそうです。