Storage Access API と CHIPS を使ってサードパーティログインする IN 2024

## これは何？
サードパーティCookieがブロックされても、Storage Access API（SAA）とCHIPSを使ってサードパーティでログインする方法のDemoです。
2024年内にChromeがサードパーティCookieをブロックすると言われてます。
ここではサードパーティCookieのログインの代替としてSAAとCHIPSを使った案を提案します。

### Storage Access APIとは
ユーザにダイアログを表示し、埋め込みコンテンツに対して「許可」を求めます。「許可」を押したユーザは以降は、サードパーティCookieの送信が可能になります。
- https://developers.google.com/privacy-sandbox/3pcd/storage-access-api?hl=ja
- https://developer.mozilla.org/ja/docs/Web/API/Storage_Access_API

### CHIPSとは
Partitioned属性のついたCookieです。
いままでのCookieとは異なり、ブラウザがサードパーティCookieをブロックの状態でもCookieの送信が可能になります。
- https://developers.google.com/privacy-sandbox/3pcd/chips?hl=ja
- https://developer.mozilla.org/en-US/docs/Web/Privacy/Privacy_sandbox/Partitioned_cookies

### Demoコード
下記におきました。
https://github.com/reojun25/saa_demo

### シーケンス
今回用意したDemoのシーケンスです。
![SAA_Demoシーケンス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246278/0d2ac50e-6bcc-c4bb-74b0-51312c21cd27.png)

- Chromeの設定を開き、「サードパーティCookieをブロックする」に設定します
- IDPにアクセスしユーザ登録します。（0. 事前に登録）
ここではIDPはTOPレベルドメインとしてアクセスします。PHPSESSIDはファーストパーティとしてSet-Cookieされます。ユーザ名はPHPのセッションとして保存しました
- RPにアクセスします。 
RPサイトはIDPサイトのコンテンツをiframeで埋め込んでます。
IDPのサイトには登録済みですが、PHPSESSIDのCookieはサードパーティにあたるためブロックされます。そのためゲスト状態の表示となります
- Storage Access APIを使用してユーザにダイアログを表示します。
- ユーザが「許可」を選択した後の、XHRリクエストではサードパーティにあたるPHPSESSIDのCookieは送信が可能になります。（2-1. XHRリクエスト）
- IDPでは受信したPHPSESSIDを検証します。
正規のセッションであれば、PHPSESSIDをPartitioned属性のついたCookieとしてSet-Cookieします。（2-1. レスポンス）
- 以降ブラウザを更新しても、RPサイトに埋め込まれたIDPサイトのコンテンツへはCookieの送信が可能になります。
サードパーティCookieがブロックされてもユーザ認証が可能になります。

### Demoコードを操作してみる
#### Chromeの設定を変更する
設定 を開き、「プライバシーとセキュリティ」を選択、「サードパーティCookie」を選択すると下記の画面になる。「サードパーティCookieをブロックする」にチェックを入れる
![1-chrome_setting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246278/c82ae6a1-8441-f8ae-aadc-07d762b5ec72.png)

#### IDPサイトで登録する
`https://<IDPサイト>/saa/idp/register.php` へアクセスします。
![3-idp_register.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246278/4e15385e-7b3b-eb9d-4822-e750d590de7f.png)
ユーザ名を入力し、登録を押します。
「RPサイトへ戻ります」 をクリックします。

#### RPサイトへアクセスする
「RPサイトへ戻ります」 をクリックすると `https://<RPサイト>/saa/rp/index.php` へアクセスされます。
下記の画面になります。
![2-rp_site.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246278/af909e9e-f92e-a8b1-9d2a-5962665f8730.png)
オレンジ色がiframe で埋め込まれたIDPサイトのコンテンツ（iframe.php）です。
DevToolsを開きます、Networkタブを選択し、iframe.phpのアクセスを選択し、Cookiesタブを選択します。下のキャプチャのように、PHPSESSIDが黄色なりブロックされていることが確認できます。
![4-3rdparty_cookie_blocked.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246278/a1e087d1-d4fe-3a5e-1102-47e86896595f.png)

Cookieがブロックされているため登録したユーザ名が確認できず、ゲストと表示されます。
Storage Access APIを使う前にサードパーティCookieがブロックされた状態でXHRリクエストをしてみます。2段目のボタン「XMLHttpRequestでCookieを確認する」を押してください。get_cookie.phpにXHRリクエストされます。
DevToolsを開き、先ほどのようにget_cookie.phpを選択し、Cookiesタブを選択します。先ほどと同じように、PHPSESSIDが黄色なりXHRリクエストでもCookieがブロックされていることが確認できます。
![6-get_cookie_blocked.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246278/d636a5f4-1bd2-0038-6c18-0d9a5b417508.png)

#### Storage Access APIを使う
「requestStorageAccess()をcall」ボタンを押します。
下記のようなダイアログが表示されます。
![5-dialog.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246278/f28ec757-fe72-d31e-2aad-6ab205e17e45.png)
「許可する」を押します。
「許可する」を押した後に、2段目のボタン「XMLHttpRequestでCookieを確認する」を押してください。
DevToolsを開き、先ほどと同じようにget_cookie.phpを選択し、Cookiesタブを選択します。下記のように、PHPSESSIDが送信されていることが確認できます。
![7-get_cookie_accepted.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246278/96958d2c-6ddc-76e4-83fd-a526da8bea49.png)

これは、**ユーザアクションでrequestStorageAccess()がcallされた後の、XHRリクエストではサードパーティCookieが送信されている**ことを示しています。これが**今回の記事で一番伝えたいこと**です。上手く使えばサードパーティCookieのブロック後の有効な対策になります。
ブラウザをリロードした後に、2段目のボタン「XMLHttpRequestでCookieを確認する」を押してください。今度はブロックされます。つまりブラウザをリロードするとサードーパーティCookieはブロック状態に戻ってしまいます。これはやや厳しい仕様ですがCHIPSと組み合わせることで対処できます。次に説明します。

#### Storage Access APIとCHIPSを使った永続的なログイン
3段目のボタン「XMLHttpRequestでログインする」を押してください。これの実装はrequestStorageAccess()をcallして、許可されていたらシーケンス図の2-1.XHRリクエストします。
![10-xhr_login_success.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246278/9e5171ed-be88-ce12-7d31-1fbf627a2824.png)

画面が切り替わり、さきほど登録したユーザ名が表示されます。COOKIEの環境変数にもPHPSESSIDが加わりました。
2-1.XHRリクエストのlogin_with_xhr.phpのレスポンスを見ると、PHPSESSIDがSet-Cookieされており、Partitioned属性がついています。
![9-xhr_login_http_resuponse_header.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246278/c522192f-8555-5676-80f4-bb6486c86583.png)
Partitoined属性をつけると、上記でも述べたとおり従来のCookieとは異なり、サードパーティコンテキストでもCookieの送信が可能になります。
このSet-Cookieを受け取り、iframeのコンテンツをリダイレクトさせたため、画面が切り替わりユーザ名が表示されました。
ブラウザをリロードしてみます。ユーザ名が表示されたままになるはずです。
Partitioned属性のついたCookieにより、サードパーティへCookieが送信されユーザ判別できているからです。Cookieの送信を見てみます。
![11-xhr_login_after_cookie.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246278/f141d4ad-6cf3-1b8b-df1b-5e069c63f71b.png)
上のPHPSESSIDがが白くなりブロックされてないことを示しています。Partitioned属性のCookieにはPartition Keyが入っています。
下のCookieは従来のCookieで引き続きブロックされていることが分かります。
このようにユーザアクションでXHRリクエストを発生させそこでサードパーティCookieを送信し、Partitioned属性のCookieを発行することで永続的なログインが可能となりました。

#### Storage Access APIの許可はどこに保存される？
サイト別の設定に保存されるようです。下記のようにブラウザのURL欄の左側のマークを押すとダイアログが表示され、埋め込みコンテンツの有効/無効として設定されます。
![12-site-setting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246278/d3dd85f7-ca51-83d8-3334-20059ae88ebc.png)