1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Auth0のUsername-Password-Authenticationはデフォルトでsessionの永続化があるのでログアウトしても再ログイン時にID/パスワードを聞かれない件

Last updated at Posted at 2023-07-11

これ

Screenshot_2023-07-11_at_10_39_00.png

問題

ログアウトしてもログアウトしてない。
下の画像のようにAuth0はデフォルトでsessionを永続化するので、ログアウトしても再ログイン時にIDとパスワードの再入力が求められずいきなりログインできる。

Screenshot_2023-07-11_at_10_06_51.png

携帯などの個々人保有端末なら問題ないが、公共のパソコンなどでログインしたりするとかなりマズい。
(パソコン1台で家族間で同じサイトにログインするとかもあるし)

ログアウトしてもログアウト出来てないから、別IDでログイン出来ないのはすごく非直感的動作

解決

上の画像の設定をNon-Persistent Sessionにすれば解決しそうだが、そうでもない。

Browser Limitations
In some cases, non-persistent sessions cannot be enforced by tenant settings. Examples include:

  • The user has a session restore setting on the browser enabled; restoring the session also restores the session cookie.

  • The user closes a tab but not the browser window; the session cookie is not cleared until the session ends based on Idle or Absolute Expiration.

要はブラウザーによりけりでこの動作は保証されない。

Auth0の中の人も

この設定があったとしてもOSXだとcommand + Qで確実にアプリケーションを落とさないとセッションが維持される

とも言ってる。

どうするのか?

auth0 api /v2/logoutを叩けと言ってる。

GET https://{yourDomain}/v2/logout?client_id={yourClientId}&returnTo=LOGOUT_URL

  1. client_id
  2. returnTo

これら2つの有無パターンがある。

  • If the client_id parameter is included, the returnTo URL must be listed in the Allowed Logout URLs set at the application level (see Setting Allowed Logout URLs at the App Level).
  • If the client_id parameter is NOT included, the returnTo URL must be listed in the Allowed Logout URLs set at the tenant level (see Setting Allowed Logout URLs at the Tenant Level).
  • If the client_id parameter is included and the returnTo URL is NOT set, the server returns the user to the first Allowed Logout URLs set in the Dashboard (see Setting Allowed Logout URLs at the Tenant Level).
  • client_idを含めるなら、returnToはテナント内のApp内のAllowed Logout URLsで設定したURLしかだめ
  • client_idを含めないなら、returnToはテナントのSettings > AdvancedAllowed Logout URLsで設定したURLしかだめ
  • client_idがあって、returnToが無いならテナント内のApp内のAllowed Logout URLsで設定した最初のURLに飛ばす

client_idをユーザー側(ブラウザ側)から見えるのはなんとなくモヤモヤするので、

GET https://{yourDomain}/v2/logout?returnTo=LOGOUT_URL
(client_id削除)

こう呼ぶとして、returnToはテナントのSettings > AdvancedAllowed Logout URLsで設定したURLにする。

Screenshot_2023-07-11_at_10_43_47.png

NextAuth.jsからだとどうするか?

自分はNextAuth.jsからAuth0をProviderとして使っているので、更に問題が厄介で

// ログアウトしたら完全にログアウトするためにAuth0のlogoutAPIを叩く
signOut({
  callbackUrl: "https://{yourDomain}/v2/logout?returnTo=LOGOUT_URL",
})

と単純にしても機能しない。

By default only URLs on the same URL as the site are allowed, you can use the redirect callback to customise that behaviour.

デフォルトだと、callbackUrlは同じサイト内のURLにしか飛ばさないよ。

なので、違うサイトのやつは無視してbaseUrl(トップページ)へ飛ばされる。

callbacks: {
  async redirect({ url, baseUrl }) {
    // こういったものを追加する
    if (url.includes("auth0.com/v2/logout")) {
      return url
    }

    // https://next-auth.js.org/configuration/callbacks#redirect-callback
    // のコピー
    // Allows relative callback URLs
    if (url.startsWith("/")) return `${baseUrl}${url}`
    // Allows callback URLs on the same origin
    else if (new URL(url).origin === baseUrl) return url
    return baseUrl
  },
}

ここまでするとやっと再ログイン時にID、パスワードを聞かれるようになる...

  1. サインアウトボタンを押す
  2. signOut()を呼ぶ
  3. callbackUrlへ行こうとする
  4. redirectでurlが処理される
  5. 自分が追加したコード部分url.includes("auth0.com/v2/logout")により直接urlへリダイレクト出来る
  6. Auth0のログアウトAPIを叩く
  7. 完全にAuth0からログアウト出来る
  8. returnToへ移動する

まとめ(NextAuth.js + Auth0 provider)

  1. Non-Persistent Sessionにする必要は特にない
  2. テナントのSettings > AdvancedAllowed Logout URLsを設定する(ログアウトして戻る場所)
  3. Redirect callbackを書き換える
  4. singOutのcallbackUrlを追加し、Auth0のLogout APIを叩くようにする
    • returnToは2.で設定したもの
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?