third party cookies(サードパーティクッキー)をブロックしたブラウザでアクセストークンを取得する – 【Auth0】

third party cookies(サードパーティクッキー)をブロックしたブラウザでアクセストークンを取得する – 【Auth0】

ライブラリ

ライブラリ バージョン
@auth0/auth0-spa-js 2.0.8

モダンブラウザがthird party cookies(サードパーティクッキー)をブロックする方向に向かっているらしいので、FireFoxでthird party cookies(サードパーティクッキー)をブロックした状態でアクセストークンを取得できるか試してみました。

以下2点を変更します。

  • トークンの保管場所をin memoryからlocalstorageに変更する
  • リフレッシュトークンローテーションを使用する

FireFoxの設定

FireFoxでthird party cookies(サードパーティクッキー)をブロックします。

これでブラウザの設定はOKです。

トークンの保管場所をin memoryからlocalstorageに変更する

auth0Client = await auth0.createAuth0Client({
  domain: config.domain,
  clientId: config.clientId,
  authorizationParams: {
    audience: config.audience, // API Identifier
    redirect_uri: config.callbackUrl, // callback url
  },
  cacheLocation: 'localstorage',
  useRefreshTokens: true,
  useRefreshTokensFallback: false 
});

createAuth0Client()メソッドでauthorizationParams.audienceを指定しました。コチラにある通り、getTokenSilently()が動作しなかったです。

cacheLocationをlocalstorageにします。認証情報をin memoryからlocalstorageに保存されるように変更します。

useRefreshTokensをtrueにします。

useRefreshTokensFallbackは省略もしくはfalseにします。

ver2.xからはuseRefreshTokensFallbackはデフォルトfalseに変わったので省略しても大丈夫です。trueを指定するとthird party cookies(サードパーティクッキー)にアクセスしようとするのでfalseにしておく必要があります。

ちなみにver2からデフォルト値がfalseに変わったのは、サードパーティクッキーをブロックしようとするモダンブラウザの流れを受けてだそうです。

you can see that we flipped the default value for useRefreshTokensFallback from true to false, this was done because more and more browsers are blocking third party cookies, and not everyone is using custom domains.

Allow to disable the use of silent auth when using Refresh Tokens by frederikprijck · Pull Request #907 · auth0/auth0-spa-js
When using our SDK in environments such as electron, where it's common to use the file: protocol, using silent auth (ifr...
Auth0 spa 2.x returning missing_refresh_token
I have been receiving errors when calling the getTokenSilently() method. The catch block receives missing_refresh_token ...

リフレッシュトークンローテーションを使用する

リフレッシュトークンローテーションを有効にします。

リフレッシュトークンの有効期限(Refresh Token Expiration)を短く設定してしまうと、有効期限が切れた場合、サイレント認証が走ってしまい、third party cookies(サードパーティクッキー)にアクセスしようとしてうまく動作しないと思われます。※useRefreshTokensFallbackは省略もしくはfalseにするとサイレント認証は行われない..って書いてた

Silent authentication requires third-party cookies supplied by Auth0 as the authorization server. However, various browsers, such as Safari, block third-party cookies by default. This means that the Auth0 SPA SDK will not be able to set cookies during authentication.

useRefreshTokensFallback:true時のリフレッシュトークン有効期限切れのログ

useRefreshTokensFallback:false時のリフレッシュトークン有効期限切れのログ

false指定時はサイレント認証が実行されていない事が確認できますが、結局のところリフレッシュトークン有効期限エラーが出てしまってアクセストークンを取得することができないので再度ログイン認証するしかないと思われます。

なので、アクセストークンの有効期限を短く、かつ、リフレッシュトークンの有効期限は長く設定する必要がある気がします。※リフレッシュトークンは都度ローテートされます

getTokenWithPopup()

getTokenWithPopup()を使用してみます。こちらのメソッドはブラウザがthird party cookies(サードパーティクッキー)をブロックしていても影響ないメソッドだそうです。

const popup = window.open(
  '',
  'auth0:authorize:popup',
  'left=1,top=1,width=100,height=100,resizable'
);
const accessToken = await auth0Client.getTokenWithPopup(
  {authorizationParams: {audience: 'https://example.com:3000/'}},
  {popup}
)

正しく動作しましたが、小さいウィンドウが一瞬表示されてしまうのでこのメソッドの使用は避けたいところです。

Auth0 Single Page App SDK
Auth0 SDK for single page applications using Authorization Code Grant Flow with PKCE.

getTokenSilently()

getTokenSilently()を使用してみます。

let accessToken
try {
  accessToken = await auth0Client.getTokenSilently()
} catch (e) {
  if (e.error === 'missing_refresh_token' || e.error === 'login_required') {
    await auth0Client.loginWithRedirect();
  }
}

正しく動作し、アクセストークンの有効期限切れのタイミングで新たにアクセストークンが取得できます。リフレッシュトークンも新たなトークンになっていることが確認できました。

気になった点としては、引数に異なるaudienceを指定して、アクセストークン取得はできなかったです。コチラにその旨の記載があります。

This only works when not using Refresh Tokens (useRefreshTokens: false), as a Refresh Token is bound to the particular audience and scope that was requested at user authentication time.

さらに、third party cookies(サードパーティクッキー)をブロックするブラウザの場合は、リフレッシュトークンを使用せずにアクセストークンは取得できませんとのことです。

Getting an Access Token silently without using Refresh Tokens will not work in browsers that block third-party cookies, such as Safari and Brave. To learn more about the custom domain workaround, read Troubleshoot Renew Tokens When Using Safari.

このことから、audienceは一つしか指定ができないのかもしれません。

Auth0 Single Page App SDK
Auth0 SDK for single page applications using Authorization Code Grant Flow with PKCE.
Login required error when using local storage and refresh tokens · Issue #542 · auth0/auth0-spa-js
Describe the problem I've configured auth0 client to use local storage and useRefreshTokens. When I try it out in Chrome...
getTokenSilently throws "Login required" with Safari · Issue #623 · auth0/auth0-spa-js
Problem description with reproduction steps Hi! I'm using "@auth0/auth0-spa-js": "^1.13.1" in a "next": "9.5.5" app. I'm...

代替案としてのカスタムドメイン

代替案としてカスタムドメインを使用すればfirst party cookies(ファーストパーティクッキー)になるのでこの色々ややこしい問題は回避できます。

が、カスタムドメインは有料プランなのと、Auth0公式ドキュメントで非推奨(クロスオリジン認証)との記載があります。

フロントエンドで入力した認証情報をクロスオリジンリクエストで送るのは危険ということです。

結論

third party cookies(サードパーティクッキー)がブロックされる前提だと以下の制約が出てきます。

  • audienceは一つしか指定できない..気がする

セキュリティやUXを考えると、トークンの有効期限について以下のような考慮が必要です。

  • リフレッシュトークンの有効期限は長く設定しないと再度ログイン認証が必要となる。アクセストークン有効期限切れのたびにリフレッシュトークンはローテートされるので、リフレッシュトークンの有効期限が長くても比較的安全と考えられる..気がする。
  • XSS攻撃を防ぐ為にアクセストークンの有効期限は短く設定する。期限が切れるとローカルストレージの情報が更新される、リフレッシュトークンもローテートされる。

参考サイト

Troubleshoot Renew Tokens When Using Safari
Issues with token renewal in Safari when ITP is enabled.
Why is authentication lost after refreshing my single page application?
Question: Why is authentication lost after refreshing my SPA? Answer: There could be a few different reasons why authent...
How to get an opaque token without 3rd party cookies
Hi, we ran into issues with getting tokens on browsers that block 3rd party cookies. We solved the issue for getting JWT...
Safariがサードパーティクッキーをデフォルトでブロック
Safariは、Webプライバシの前進を目指す行動のひとつとして、サードパーティクッキーをデフォルトでブロックすることにより、TorやBraveのようなプライバシ重視のWebブラウザの仲間入りを果たした。一方でGoogleは、すべてのChr...
Google、サードパーティCookie完全廃止に向けて2024年Q1にChromeユーザーの1%で無効に
Googleは、2024年第1四半期にChromeユーザーの1%のサードパーティcookieを無効にすると発表した。また、Chrome 115で、開発者がより広範な規模でプライバシーサンドボックス対応のテストを行えるようにする。Google...

コメント

タイトルとURLをコピーしました