この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
前回に引き続き、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の認証