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

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

新規登録して質問してみよう
ただいま回答率
85.46%
Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

0回答

804閲覧

Rails devise token auth リクエスト毎のトークン変更について

orori

総合スコア42

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

1グッド

1クリップ

投稿2021/08/02 01:22

編集2021/08/19 00:57

バックエンドはRails6、フロントはReact.jsで商品販売系のWebアプリを作成しています。
認証については、gemのdevise token authを採用しました。

このdevise token authですが、リクエスト毎に認証トークンを変更する方法がオプションで選択できるようになっていますが、
これを実現する場合、メール認証の場合(今回メール認証を行う予定)、毎回のリクエスト時に、IDとパスワードを入力するような方法しかないと考えておりますが、いかがでしょうか。
そして、これでは、販売系の一般的なアプリとして成立しないのでは、と思われます。

また、リクエスト毎にトークンを変更する方法をとらずに、ブラウザのローカルストレージにトークンを保存した場合、
例えばこれがデフォルトの設定値の2週間であっても他者にこれをぬき取られてしまう危険性があると各所にかかれていました。
では、一般的に、このdevise token authはどのように利用されているのでしょうか。

なかなか一般的というのが難しいとは思いますが、ご教示いただけますと幸いです。

ーーーーーーーーーー
shinoharat様の回答によって、サインインにリクエストしなくとも、毎回のリクエストで新たなトークンが取得されることが確認できました。大変にありがとうございました。

ただ、この状態でブラウザを落として、再びページをみてみると最後のリクエストで取得したトークンでログインが可能となっていました。 とすると、他者にこれを抜き取られた場合、ログインが可能となってしまうのではないでしょうか。

とりあえずひとつ解決しましたので、質問を別途立ち上げたいと思います。

shinoharat👍を押しています

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

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

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

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

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

shinoharat

2021/08/10 07:23

> 毎回のリクエスト時に、IDとパスワードを入力するような方法しかないと考えておりますが、いかがでしょうか。 リクエスト時に必要なトークンなどは、直前のレスポンスに含まれていますので、リクエストのたびにユーザがIDとパスワードを入力するってことは無いですが、そういう意味ではなくですか? それとも、一旦ブラウザを落として再度アクセスしたときの話をされていますか? (俗にいう「ログイン状態を保持する」みたいな機能が実装出来ないのでは?という懸念ですか?)
orori

2021/08/11 00:07

回答、ありがとうございます! >直前のレスポンスにふくまれています とのこと、axiosでresponseのヘッダーを見ているのですが、必要なaccessToken, client, uidが含まれていないようです。公式をみなおしましたが、見当たらないようです。/auth/sign_in/にリクエストしたときはこれらがあるのですが・・・ 上の部分がクリアできていなかったので、ブラウザを落とした場合の動作についてまで考えておりませんでしたが、「ログイン状態の保持」は実現してほしいです。 ブラウザを落とした場合、最後のリクエストから帰ってくるトークンをローカルストレージにいれておけばこれは可能になるのでしょうか?
shinoharat

2021/08/11 05:50

> axiosでresponseのヘッダーを見ているのですが、必要なaccessToken, client, uidが含まれていないようです。 コントローラーに以下の concern を include してもダメでしょうか? ``` class ApplicationController < ActionController::Base include DeviseTokenAuth::Concerns::SetUserByToken end ``` 参考URL https://devise-token-auth.gitbook.io/devise-token-auth/usage/controller_methods#concerns -- 聞くまでもないかもしれませんが、 config.change_headers_on_each_request = true にはなっていますよね?
orori

2021/08/12 02:02

ありがとうございます。はい、ご指摘の2点は問題ないです。 もう少し詳細に調べてみました。 sign_inのレスポンスで戻ってくるヘッダーの内容をローカルストレージにいれて、 次リクエストをだしますと、レスポンスには、以下のように、access_tokenとexpiryがなくなっています。 これをまたローカルストレージにいれてリクエストすると、当然ですがログアウトされてしまいます。 access-token: "" cache-control: "max-age=0, private, must-revalidate" client: "JHMm5CjU77LvzqU2pwHOyw" content-type: "application/json; charset=utf-8" expiry: "" 以下のような関数をつくって、レスポンスのヘッダーから 必要な要素を都度ローカルストレージに入れてみているのですが・・ export default function setLocalStorage(headers){ console.log(headers) console.trace() window.localStorage.setItem('accessToken', headers['access-token']) window.localStorage.setItem('client', headers.client) window.localStorage.setItem('expiry', headers.expiry) window.localStorage.setItem('uid', headers.uid) } 長くなってすみません。よろしくお願いいたします。
shinoharat

2021/08/12 03:04

> これをまたローカルストレージにいれてリクエストすると、当然ですがログアウトされてしまいます。 一応、、、念のため確認させてください。 ローカルストレージにセットした認証ヘッダ情報は、次のリクエストを送るときに再度ヘッダに設定していますよね? ``` const auth_headers = { "access-token": window.localStorage.getItem("accessToken"), "client": window.localStorage.getItem("client"), "uid": window.localStorage.getItem("uid"), } axios.get(url, params, { headers: auth_headers }) ```
orori

2021/08/12 03:20

はい、ほぼご指摘のとおりローカルストレージから読み出してaxiosに設定しています。 都度変更しない場合はログアウトせずきちんと動きますので、axiosの設定には問題ないかと思います
shinoharat

2021/08/12 08:24

うーん、、じゃあバッチリクエスト扱いになってるとかですかね? 「axios の params に { unbatch: true } を追加する」 または 「devise_token_auth.rb の batch_request_buffer_throttle を 0秒にする」 で再度試していただけますか? -- それでも解決しない場合は、現在のコードを丸ごと質問文に追加してもらった方が早いかも知れないです。
orori

2021/08/15 02:53 編集

ありがとうございます、どうにかうまくいきました! >「devise_token_auth.rb の batch_request_buffer_throttle を 0秒にする」 を行ってみましたところ、レスポンスのヘッダーのauth-tokenが空欄にならなくなりました。そして、それをいれてリクエストすると、新たなトークンが取得できました。 >「axios の params に { unbatch: true } を追加する」 も試したいのですが、どのように設定するか、お手数ですがドキュメントなどお教えいただけますと幸いです。 他の方にも役立つように質問を追記・修正しますね。
shinoharat

2021/08/15 05:06

うまくいったようで良かったです。 > >「axios の params に { unbatch: true } を追加する」 > も試したいのですが、どのように設定するか、お手数ですがドキュメントなどお教えいただけますと幸いです。 すみません、僕も unbatch に関する公式なドキュメントは知らなくて、 「github のソースコードを見た感じ unbatch が使えそうだなー」 って感じでコメントしました。 https://github.com/lynndylanhurley/devise_token_auth/blob/5c0baba8aaf005d03daeaf425d555739d3215603/app/controllers/devise_token_auth/concerns/set_user_by_token.rb#L155 -- バッチリクエスト自体のドキュメントは↓です。 https://devise-token-auth.gitbook.io/devise-token-auth/conceptual#about-batch-requests 「短い間隔(デフォルトだと5秒)でリクエスト送るとバッチリクエストとして認識する」 「バッチ内の後続のリクエストはトークンを返さない」 といった説明があります。 -- (これはご存知かとは思うのですが)axios でリクエストパラメーターを設定したい場合は、第2引数の config に { params: { ... } } を加えます。 ``` const auth_headers = { "access-token": window.localStorage.getItem("accessToken"), "client": window.localStorage.getItem("client"), "uid": window.localStorage.getItem("uid"), } axios.get(url, { params: { unbatch: true }, headers: auth_headers }) ``` https://axios-http.com/docs/api_intro https://axios-http.com/docs/req_config
orori

2021/08/16 12:30

axiosについて知っておりましたが、他見る方には参考になるかと思います。 今回は大変にありがとうございました。 今回はここで解決として、もともと複数の質問がありましたので、 別途質問をたちあげたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問