Rails で ログインAPI を作るなら、devise_token_authがおすすめです。
ほとんどの人は devise で user 管理をしているでしょうから、それを拡張する形で導入できます。
Next.js とかからも利用できます。
まず、以下を実行します。
% bundle exec rails g devise_token_auth:install User auth
すると、以下のようなルーティングが自動生成されます。
config/routes.rb
Rails.application.routes.draw do mount_devise_token_auth_for 'User', at: 'auth' end
このルートの実態は以下のようになります。
/auth/sign_in がサインイン
/auth がサインアップ
て感じですね。
% bundle exec rails routes GET /auth/sign_in(.:format) POST /auth/sign_in(.:format) DELETE /auth/sign_out(.:format) GET /auth/password/new(.:format) GET /auth/password/edit(.:format) PATCH /auth/password(.:format) PUT /auth/password(.:format) POST /auth/password(.:format) GET /auth/cancel(.:format) GET /auth/sign_up(.:format) GET /auth/edit(.:format) PATCH /auth(.:format) PUT /auth(.:format) DELETE /auth(.:format) POST /auth(.:format) GET /auth/validate_token(.:format)
devise_token_auth は以下のカラムを利用してそうです。
provider
uid
token
リクエストごとに、以下の httpヘッダーが返ってくるようです。
HTTP/1.1 200 OK access-token: xzTWhTURMmPdDjaKB2R9gw token-type: Bearer client: S2T6zY0aDB6VBXYVMdpjbg expiry: 1558871460 uid: example@example.com
以下のように説明されています。
access-token
これはリクエスト毎にユーザーのパスワードとして提供されます。この値のハッシュ・バージョンは、後で比較するためにデータベースに保管されます。この値はリクエスト毎に変更されるべきです。client
これにより異なるクライアント上で複数の同時セッションを管理することができます。たとえば、携帯電話とラップトップの両方で同時に認証を受けたい場合があります。expiry
現在のセッションが失効になる日にちです。これは、クライアントがAPIリクエストを必要とせずに期限切れのトークンを無効にするために使用できます。uid
ユーザーを識別するために使用される一意の値。アクセストークンでユーザーのDBを検索すると、APIがtiming attacksを受けやすくなるため、これが必要です。
以下の設定がいじれます。
change_headers_on_each_request ですが、これは false にしておいた方がよさそうです。
trueにしたままだと、ログインセッション一本だけしかできなそうなので、不便じゃないでしょうか。
つまり、同一ブラウザの複数タブで作業してると、他のが強制ログアウトされてしまいそう。
もちろん、セキュリティ度をあげたいなら、良いです。
上記 header の client の項目があるので、複数ブラウザがokならばよい、という意味ならこれを true にしても問題なさそう。
デフォルトではそれぞれのリクエストの後にaccess-tokenヘッダが変わります。
クライアントは変更されるトークンを追跡し続ける責務があります。
ng-token-authとj-tokerの両方でこれが実行されます。
これは安全ですが、管理が難しいです。
この設定をfalseにすると、リクエスト毎にトークンヘッダが変更されなくなります。
config/initializers/devise_token_auth.rb
DeviseTokenAuth.setup do |config| # リクエストごとにトークンを更新するか # 扱いやすいようにFalseにします config.change_headers_on_each_request = false # トークンの有効期間 # デフォルトでは2週間です config.token_lifespan = 2.weeks # ヘッダーの名前対応 config.headers_names = {:'access-token' => 'access-token', :'client' => 'client', :'expiry' => 'expiry', :'uid' => 'uid', :'token-type' => 'token-type' } end
ソースコード
devise – rubygems.org
https://rubygems.org/gems/devise
heartcombo/devise
https://github.com/heartcombo/devise
devise_token_auth – rubygems.org
https://rubygems.org/gems/devise_token_auth
lynndylanhurley/devise_token_auth
https://github.com/lynndylanhurley/devise_token_auth
参考記事
【翻訳】devise-auth-token公式ドキュメント – 2018年8月11日
https://sainu.hatenablog.jp/entry/2018/08/11/194319
【Rails API 入門】devise-token-auth – 2020年05月06日
https://qiita.com/tomokazu0112/items/5fdd6a51a84c520c45b5
Rails API + React + devise_token_authでログイン機能を実装する
https://qiita.com/kazama1209/items/caa387bb857194759dc5
[Rails] devise token auth を使う – 2020年09月14日
https://qiita.com/Masahiro_T/items/6bc49a625b437a7c2f45
Cookie(Session)での認証とTokenでの認証の違いについて
https://magazine.techcareer.jp/technology/skill/11273
[rails]既存のdevise を入れた後にdevise_token_authを追加、API化する時 – 2020年12月13日
https://qiita.com/gonza_kato_atsushi/items/9b6e92e636825ce91501
DeviseとDevise token authを共存させる(後から追加する) – 2019年11月07日
https://qiita.com/wktq/items/8a4653153af47933c169
あんまよく知らなかったんですが、railsってマイグレーション中にこういう風に処理も書けるんですね
class AddTokensToCustomers < ActiveRecord::Migration[6.0] def up add_column :customers, :provider, :string, null: false, default: 'email' add_column :customers, :uid, :string, null: false, default: '' add_column :customers, :tokens, :text Customer.reset_column_information Customer.find_each do |customer| customer.uid = user.email customer.provider = 'email' customer.save! end add_index :customers, [:uid, :provider], unique: true end def down end end
devise + devise token authでWebにもアプリにも対応 – 2019年10月22日
https://qiita.com/DaichiSaito/items/b6239d70ab10b2070bc4
普通の devise の場合
ところで何気なく使ってる通常の devise のログインセッションで
どうやって保存されてるんでしょうか?
クッキーに保存していると思いますが、その値は?
まさか、user_id そのままではないでしょう。
warden + secret key が関係してそうですが、
詳細はわかりません、分かり次第追記します。
Deviseのモヤモヤを解消して快適なRailsライフを送ろう! – 2020年12月25日
https://zenn.dev/kitabatake/articles/start-to-like-the-devise
Railsのsecret_key_baseを理解する(翻訳) – 2017年10月24日
https://techracho.bpsinc.jp/hachi8833/2017_10_24/46809
warden のコードリーディング – 2020年6月5日
https://ogidow.hateblo.jp/entry/2020/06/05/105208
Wardenの使い方 まとめ – 2018年10月27日
https://nekorails.hatenablog.com/entry/2018/10/27/172832
Devise を知るにはまず Warden を知るが良い
http://vimtaku.github.io/blog/2014/03/02/warden
コメント