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

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

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

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

3回答

1188閲覧

Ajaxの処理について

k499778

総合スコア599

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2017/07/24 15:25

編集2017/07/25 19:39

現在上記タグでWebアプリケーションを作っています。FWはDomaです。

今登録処理を作っていてCSRF対策の対応を入れています。
画面のモーダル内のボタン押下時にその登録処理が走り、完了モーダルが表示されるつくりです。
その ボタン押下→登録→モーダル表示 の流れをAjaxを使って行っています。

質問があって
結論から言うと
AjaxでSession情報を送れていたのにある時から急に送れなくなった原因は何だと推測されるでしょうか?
という点です。

詳しく説明すると、
CSRF対策用の情報を画面の初期表示時にSessionに詰め込み(HogeActionクラス)、
登録ボタン押下時にAjaxでSession情報を渡し、サーバー側(FugaAction)で受け取る実装になっている。
たしかFugaActionクラスではHttpRequestクラスを使ってSession情報を受け取っていた?
AjaxのSession情報の維持の仕方は以下サイトを参考にし、次のコードを追記した。
SESSION情報を維持したままAjaxな処理を行う方法

javascript

1 beforeSend: function(xhr) { 2 xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content')); 3 },

先週末までこの実装でSession情報の受け渡しができていたのだが、
本日急にSession情報が受け取れなくなりました。
受け取るパラメータの一つであるHttpRequestクラスの中のsession情報がnullで返ってくるようになっていたのです。
コードもできていたときと特に変わっていないし、他の画面ではこの流れの実装が問題なく動くところもあるのです。
もちろんチーム開発ですので、他の共通部分や何かしらの環境が変わったなどあるかもしれませんが、
いまいち原因と対応策をつきとめられずにいます。

Session周りは調査するのも難しく、私もほとんど慣れていないので、どういった原因がありえるのかいまいち把握できていません。

もしそのような経験のある方、推測される原因・対応策をお教えくださる方、なんでもいいのでアドバイスをくださる方がいらっしゃればお願いいたします。


追記

そもそもやり方が間違っていました。
リンク先のやり方では、サーバー側の値を渡していないので結局クライアントとクライアントの値を比べることになってしまいます。
これでは改ざんされる恐れもあるので要件を満たしていませんでした。

そのためajax側でsession情報を渡す処理が必要になります。

そのやり方をもし知っている方がいれば教えていただきたいです。

送信部分のコード

javascript

1$.ajax({ 2 url: "/fuga/", 3 type: "POST", 4 data: { 5 "foo" : "bar", 6 "key" : $("#key").val() 7 }, 8 success: function() { 9 alert("登録できました"); 10 }, 11 error: function() { 12 alert("登録に失敗しました"); 13 } 14});

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

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

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

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

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

think49

2017/07/25 06:00

「もちろんチーム開発ですので、他の共通部分や何かしらの環境が変わったなどあるかもしれません」とありますが、チーム内の他の人に尋ねてみたのでしょうか。それを確認しない事には原因も対応策も突き止められないように思います。
k499778

2017/07/25 09:39 編集

チーム内の人にも尋ねてみました。そして今のやり方では要件を満たさないこともわかりました。 なので他の方法を探しています。 具体的にはajaxでセッション情報を渡す方法です。 したいこととしてはActionクラスでクライアント側とサーバー側のトークンの値を比べれるようにしたいです
think49

2017/07/25 09:57 編集

「先週末までこの実装でSession情報の受け渡しができていた」のですから、先週末から2017/07/25現在までの間に変更したコードに問題がある事は確実なわけですよね。ならば、変更したコードの全箇所を見直すのが前向きな切り分けなのではないか、というのが私の指摘です。
think49

2017/07/25 09:58

現在の状況は「どこを変更したのかわからない」「何が原因かもわからない」ですが、せめて「どこを変更したのかはわかったが、何が原因か分からない」まで進めた方が良いと私は思います。
k499778

2017/07/25 10:04

返答ありがとうございます。 補足や他の方のコメントにも記載しましたが、そもそも実装としておかしかったという現状があります。 なので今は正しい方法を探しています。 前回偶然にも動いてしまったのは他のセッション情報が影響したと考えられます。 gitのログも追いましたが、やはりソースコードの変化は見られませんでした。
guest

回答3

0

参考にされているサイトがPHPなので大丈夫なのだろうか…という一抹の不安がありますが、それはさておき、

CSRFトークンチェックの機構はDomaで提供されるものではなく、他のフレームワークないしはチームの方が作成されたものでしょうか。
もしおっしゃっている現象から推察されるのは、CSRFトークンチェックで失敗した場合に、セッションを破棄する実装が共通処理(サーブレットフィルタなり、Injectされた機能なり)にて無効化されているとか、セッション情報が渡されているはずの状態だと思っていたが、セッション情報を格納する画面なりActionを経由していないので動作しなくなったなどあるでしょう。

いずれにせよ、CSRFのトークンチェック機構としてHTTPヘッダにX-CSRF-Tokenを追加するのは、サーバ側の実装とあわせて行うものですので、推測の域は出ません。

投稿2017/07/24 16:13

A-pZ

総合スコア12011

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

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

k499778

2017/07/24 22:28

回答ありがとうございます。 そうですね、トークンチェックの機構はチームで作成されたものです。 その中でセッションを破棄する処理も行なっています。
A-pZ

2017/07/25 05:51

であればセッションが破棄されたのではないでしょうか。
k499778

2017/07/25 09:31

リンク先のやり方では要件を満たせでいませんでした。 結局クライアント側とクライアント側の一致チェックになってしまうためです。 そしてむしろ動いたのがおかしかったようです。渡ってくるはずのないsession情報が何かの原因で渡ってきて、うまくいったと思ってしまいました。 なので今はajaxでセッション情報を渡す方法を探しています。 もし知っていたら共有お願い致します。
A-pZ

2017/07/25 09:49

大変申しわけないのですが、少なくとも送信部分のソースコードがなければ回答しようがありません。
k499778

2017/07/25 19:39

一部追記しました。
A-pZ

2017/07/26 02:32

CSRFチェックをするためのトークンはどこで送信されているのでしょうか?ブラウザの開発者モード・デバッグモードなどを使って送信したリクエスト情報は確認し、かつ質問中にもありましたように、「トークンチェックの機構はチームで作成されたもの」に従った送信をできているか、チームの方に確認されるのが一番早いでしょう。
k499778

2017/07/27 09:47

回答ありがとうございます。 今一度確認してみます!
guest

0

参考サイトも何言ってるかよくわかりませんが...。
(そもそもCSRFのトークン発行ってサーバが起点にならんとダメなような気がするが、サイト中"そのトークンを発行している。"ってクライアントさしてるよな...。)
で、もうちょっと情報がほしいのですが...。
a.「ある時から急に送れなくなった」原因は不明としてもトリガーになりそうなアクションてなにかあったのでしょうか?
(非同期処理を入れたあと?関係ないところいじったら突然?なにもしてないけど突然等々)
b.「受け取るパラメータの一つであるHttpRequestクラスの中のsession情報がnullで返ってくるようになっていたのです。」
->ここの"session情報"ってHttpServletRequest#getSessionの値でしょうか(HttpSessionはパラメータじゃないけども)?それとも独自のなにかでしょうか?
※独自のなにかであるならブラウザ側ではどこに保持しているものなのかわかりますか(hidden、cookie、ローカルストレージ等々)?→これが回答の全てだと思いますが...

ちなみに今回のケースにあてはまるかどうかわかりませんが、参考までに。
IPA等で提唱されているCSRF対策と非同期処理って相性悪いのでよくトラブルになります。
いわゆる普通のCSRF対策は
1.サーバでトークン発行
2.画面表示時にhiddenに1で発行したトークンを保持
3.次回送信時に2で保持した値を送信
4.1と2の値が同じだったらOK、古いトークンを破棄して再び1へ
ですが、画面全体を書き換えないAjaxでは2がスキップされて(1はやる)4でエラーになるってよくあります。

投稿2017/07/25 04:52

kurokoba

総合スコア276

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

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

k499778

2017/07/25 09:39 編集

回答ありがとうございます。 おっしゃる通りリンク先のやり方は結局前提としてmetaタグにトークンの値を埋め込んでの話だったので、意味がありませんでした。 一応やろうとしている流れとしては以下です。 1.画面表示時にcsrf用の値を生成し、セッション(サーバー側)と画面にhiddenで埋め込む(クライアント側) 2.登録ボタン押下時にajaxで処理 3.Actionクラスでセッション(サーバー側)と画面に埋め込んだ値(クライアント側)が一致しているかチェックし、登録処理 2でクライアント側で値は渡せるのですが、セッションの値を渡せません。 この方法が知りたいと思っています。
k499778

2017/07/25 09:37

そしてHttpServletRequest#getSessionで合っています。 ただこれは経由ルートの話なので、 ajaxのdataパラメータでsession情報を渡せるならそれでもいいと勝手に思ってます。 そのajaxでセッション情報を渡す方法が知りたいですね。
kurokoba

2017/07/25 10:13

すみません、ちょっと片手間なので簡単に...。 恐らく「Ajaxでcookieが渡ってこないから」という問題に帰結するとおもいます。 ※ 一応確認のため基本的なところから書きますと、HttpSessionってなんぞやといえばキーがセッションID、値がHttpSessionのMapみたいなもので管理されてるサーバ上のメモリの値。これ自体は基本的には通信に乗らない。 通信に乗らないのにどうして各リクエストが自分のHttpSessionを特定できるかというとクライアントからリクエストで毎回セッションIDを送信しているから。 で、クライアントのセッションIDはどうやって保持・送信されているかといえば(他にもやり方はあるが)普通はcookieつかってることが多い。 cookieでセッションIDを保持・送信している場合cookieが送信されないと当然サーバはHttpSessionを特定できない。→その結果質問のケースになります。
kurokoba

2017/07/25 10:17

例えばAjaxクロスドメインだったりしますか?
k499778

2017/07/25 19:51

回答ありがとうございます。 Ajaxクロスドメインになっていると自信をもってまだ言えないのですが、なっているかもしれません。 『セキュリティ上、Ajaxを使用するHTMLファイルが置かれているドメインのサーバとしか通信できない制約があります。 この制約をクロスドメイン制約と呼びます。』 とあって、現在の実装では htmlを表示しているActionクラスがHogeActionで AjaxではFugaActionを使用しているためドメインが https://xxxx/hoge(画面表示時)https://xxxx/fuga(Ajax使用時) と変わっています。 なのでクロスドメインかなと思っているんですが、合っていますでしょうか?
guest

0

自己解決

解決しました。
結論から言うと、
Ajaxでのセッションの受け渡しは必要なく、
Cookie情報を画面に渡すとセッション情報のid,jsessionidが画面に上書きされないことが原因のようでした。そのためセッション情報がAction間で渡されませんでした。
FWはjerseyを使っていて上記のようにCookie情報を渡すとjsessionidが渡されなくなるかに関連する記事を探したのですがそれは見つけることができませんでした。

解決法としては、Cookie情報を画面に渡す際はjsessionidも同時に渡すようにしました。

ご協力くださった皆様ありがとうございました。感謝しています。

投稿2017/07/31 23:03

k499778

総合スコア599

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問