[Ruby on Rails]sorceryによる認証 – (5)APIでの認証 #3 モデル
はじめに
前回に引き続き、APIでの認証をsorceryを使って行うサンプルについてです。今回はモデルのソースコードを取り上げます。
ソースコード
以下、モデルのソースコードになります。
User
app/models/user.rb
class User < ActiveRecord::Base authenticates_with_sorcery! has_many :api_keys, dependent: :destroy validates :password, length: { minimum: 3 } validates :password, confirmation: true validates :password_confirmation, presence: true validates :email, uniqueness: true def self.login?(access_token) api_key = ApiKey.find_by_access_token(access_token) return false if !api_key || !api_key.before_expired? || !api_key.active return !self.find(api_key.user_id).nil? end def activate if !api_key return ApiKey.create(user_id: self.id) else if !api_key.active api_key.set_active api_key.save end if !api_key.before_expired? api_key.set_expiration api_key.save end return api_key end end def inactivate api_key.active = false api_key.save end private def api_key @api_key ||= ApiKey.find_by_user_id(self.id) end end
「validates」で始まるエラーチェックについては公式チュートリアルとほぼ変わりまりません。
login?メソッドは、クライアントから渡されるAccessTokenを引数として受け取り、該当するユーザがログイン状態かどうかを返却します。具体的にはAccessTokenに該当するApiKeyモデルを取得し、存在するか・有効期限内か・activeの値がtrueかを調べます。これらの実装は後述するApiKeyモデルを参照してください。
activateメソッドは、ユーザをログイン状態にするメソッドです。ApiKeyが存在しない場合は作成し、存在する場合はactiveをtrueにすること・有効期限の再設定を行っております。
inactivateメソッドは、activateとは逆にユーザをログアウト状態にするメソッドです。ApiKeyのactiveをfalseにしています。
ApiKey
次にApiKeyモデルです。
app/models/api_key.rb
class ApiKey < ActiveRecord::Base before_create :generate_access_token, :set_expiration, :set_active belongs_to :user def before_expired? DateTime.now < self.expires_at end def set_active self.active = true end def set_expiration self.expires_at = DateTime.now + 1 end private def generate_access_token begin self.access_token = SecureRandom.hex end while self.class.exists?(access_token: access_token) end end
before_expired?メソッドは有効期限内かどうかを判定して返却しています。set_activeメソッドはユーザをログイン状態とするためactiveをtrueに変更します。set_expirationメソッドは有効期限を設定しており、今回はログインから1日だけ有効としました。generate_access_tokenメソッドはAccessTokenを生成するメソッドです。ランダムでトークンを生成しています。
set_active、set_expiration、generate_access_tokenはApiKeyの生成時に実行されるよう、before_createにて呼び出されるようにしています。
まとめ
sorceryによるAPIでの認証についての主なロジックは以上となります。API固有の部分は独自に実装することになりますが、sorceryはシンプルであるため何を実装しなければならないかが分かりやすいかと思います。業務の都合上、認証についてある程度は独自に実装しなけらばならないことが分かっている場合、sorceryを検討してみてもいいかもしれません。
今回作成したソースコードは以下のGithubに置いてあります。全ソースを見たい方は参考にしてください。 sorcery_api_sample
参考サイト
今回は以下のサイトを主に参考にさせて頂きました。ありがとうございました。
Simple Password Authentication
Securing an API
Rails + Grape + API Keyの認証