質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%

Q&A

解決済

1回答

2335閲覧

ALBとCognitoを使用してログインした後の画面に、ログアウト機能とログアウト後にログイン画面にリダイレクトする機能を追加したい。

GtEry..K_dAP-

総合スコア3

0グッド

1クリップ

投稿2022/12/27 07:53

編集2022/12/27 09:24

前提

AWSのEC2にwebサーバーを構築し、ALB経由でアクセスしています。今回、ALBにCognitoの認証機能を追加し、認証を通ったユーザーのみwebページを表示できるようにしました。

実現したいこと

アクセスしたwebページにログアウトボタンを設置し、ボタンを押下した際にログアウトが行われログイン画面にリダイレクトされるような処理を追加したいです。

発生している問題・エラーメッセージ

ブラウザからcgiを呼び出して、セッションcookieの削除とログアウトエンドポイントのurlへリダイレクトを実施しました。ログアウトエンドポイントからサインインエンドポイントへのリダイレクトは成功しているのですが、画面がログイン画面に切り替わりません。また、再読み込みをするとセッションcookieが復活してしまいます。

ソースコード

javascriptのsignOut関数をbuttonのonClickに紐づけて、ボタンが押されるとperlで作成したcgiが動作するような仕組みにしました。

javascript

1// サインアウト関数 2async function signOut() { 3 try { 4 // GETパラメータを作成 5 const params = { 6 client_id: client_id, 7 redirect_uri: 'https://{ドメイン}/oauth2/idpresponse', 8 response_type: 'code', 9 scope: 'openid', 10 }; 11 const query = new URLSearchParams(params); 12 13 // CGIを呼び出し 14 const url = `https://{ドメイン}/cgi/logout.cgi?${query}`; 15 await fetch(url, { 16 mode: 'no-cors', 17 }); 18 } catch(e) { 19 // エラー処理 20 } 21}

perl

1use CGI; 2 3# ログアウトエンドポイント 4my $logoutEndpoint = 'https://example.auth.ap-northeast-1.amazon.com/logout'; 5 6my $_q = new CGI(); 7 8# GETパラメータ作成 9my %paramHash = ( 10 client_id => $_Q->param('client_id'), 11 redirect_uri => $_Q->param('redirect_uri'), 12 response_type => $_Q->param('response_type'), 13 scope => $_Q->param('scope') 14); 15my $uri = createGetParametar($logoutEndpoint, \%paramHash); 16 17# 削除Cookie 18my $deleteSessionCookie0 = $_Q->cookie( 19 -name=>'AWSELBAuthSessionCookie-0', 20 -value=>'', 21 -expires=>'-1d' 22); 23my $deleteSessionCookie1 = $_Q->cookie( 24 -name=>'AWSELBAuthSessionCookie-1', 25 -value=>'', 26 -expires=>'-1d' 27); 28 29# 応答出力 30print $_Q->header(-cookie=>[$deleteSessionCookie0,$deleteSessionCookie1], -location=>$uri); 31 32# GETパラメータ付与関数 33sub createGetParametar{ 34 my $url = @_[0]; 35 my %paramHash = %{@_[1]}; 36 my @paramArr = (); 37 while(my($key, $value) = each(%paramHash)){ 38 my $elem = "$key=$value"; 39 push(@paramArr, $elem); 40 } 41 return $url . '?' . join('&', @paramArr); 42}

試したこと

ログアウトcgiを実行して、https通信でセッションcookieを削除してログインエンドポイントにリダイレクトした際に、このタイミングなのかは不明なのですがcognitoとXSRF-TOKENという名前のcookieが生成されていました。この2つは認可エンドポイントにリクエストした際に、cookieとしてセットされているようなのですが、セッションcookieを削除するまでブラウザの開発者ツールに表示されていませんでした。試しに、cognitoという名前のcookieを削除して再読み込みしたところ、ログイン画面が表示されました。

セッションCookieとcognito、XSRF-TOKENのドメインがそれぞれ自分独自のドメイン、cognitoユーザープールのドメインになっていることを確認しました。もしかしたら、ドメインが違うためにただ表示されていないだけの可能性もあるのかなと思いました。

もし何か知りたい情報があれば、できる限りご提供させていただきます。
お力添えのほど、何卒よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yuma.inaura

2022/12/27 07:56

プログラムはどんなコードなんでしょうか?
GtEry..K_dAP-

2022/12/27 08:21

ソースコード追加させていただきました。
guest

回答1

0

自己解決

解決方法

リダイレクトをfetchした結果からではなく、window.location.hrefによるリダイレクトでフロントエンドから実行した。

javascript

1await fetch(url) 2 .then((res) => { 3 window.location.href 4 = `https://example.auth.ap-northeast-1.amazon.com/logout?${クエリパラメータ}`; 5 })

ハマった原因

  • リダイレクトということで、サーバーサイドからのレスポンスによるものだと固執していた。リダイレクトするならフロントエンドだけでも良かった。ただし、Cookieの削除は必要になるのでサーバー側の処理は必要。
  • 修正前のコードだと、modeをno-corsにすることでcorsを無効にしているつもりだったが、corsエラーは発生しないが、取得結果が失敗しているということに気づかなかった。ステータスコードが0、レスポンスbodyが空になっていた。

確認した方がいいと思うこと

  • リダイレクトの手段、それによる違いを確認する。今回はwidnow.location.hrefを使用したが、他にも方法があるのかfetchだとなぜできなかったのか。

補足情報(2022/01/16追記)

調べてみたところホストされたUIを使用している場合、ajaxなどの非同期処理を行った際にCORSエラーが発生するのは現時点(2022/01/16)での仕様ということでした。
ホストされたUIの場合、CORSの設定を行うことができない状態ですがこの問題が解決される時期等は不明とのことです。
現状は、ブラウザから直接リクエストを送信する方法でCORSエラーを回避するしかないようです。

投稿2023/01/06 01:13

編集2023/01/16 06:20
GtEry..K_dAP-

総合スコア3

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問