はじめに
クライアントからリクエスト時にaccess_tokenを付与して、認証の実装を完成させましょう。
すなわち、Rails-APIでもcurrent_userを使えるようにするということです。
baseコントローラーに追記
baseコントローラーに、authenticate
メソッド、current_user
メソッド、set_access_token!
メソッドを追記します。
module V1
class BaseController < ApplicationController
include Api::ExceptionHandler
include ActionController::HttpAuthentication::Token::ControllerMethods
before_action :authenticate
protected # サブクラスでも呼び出せる
def authenticate
authenticate_or_request_with_http_token do |token, _options|
@_current_user ||= ApiKey.active.find_by(access_token: token)&.user
end
end
def current_user
@_current_user
end
def set_access_token!(user)
api_key = user.activate_api_key!
response.headers['AccessToken'] = api_key.access_token
end
private
# https://github.com/NoamB/sorcery/issues/724
def form_authenticity_token; end
end
end
end
protected
protected
とすることで、クラス外から呼び出せなくなります。pribate
との違いは、サブクラス(継承先の子クラス)でも呼び出せます。authenticate
メソッド
中で使われているauthenticate_or_request_with_http_token
メソッドが重要になります。 こちらを実行することで、クライアントからリクエストする際のAuthorization: Bearerヘッダーに含まれているトークンを渡して、トークンに紐ついたユーザーを探し出します。 そしてそのユーザーデータをcurrent_user
として保持します。
def authenticate
authenticate_or_request_with_http_token do |token, _options|
@_current_user ||= ApiKey.active.find_by(access_token: token)&.user
end
end
@_current_user
@_
はローカルキャッシュとして扱う場合の命名規則。
つまり@_current_user
を直接使わないでほしいということ。
authenticationsコントローラーに追記
ログイン処理を行う際はauthenticate
メソッドをスキップさせます。
module Api
module V1
class AuthenticationsController < BaseController
skip_before_action :authenticate
def create
@user = login(params[:email], params[:password])
raise ActiveRecord::RecordNotFound unless @user
json_string = UserSerializer.new(@user).serialized_json
set_access_token!(@user) # レスポンスヘッダーにAccessTokenを付与
render json: json_string
end
end
registrationsコントローラーに追記
module Api
module V1
class RegistrationsController < BaseController
skip_before_action :authenticate
def create
@user = User.new(user_params)
if @user.save
json_string = UserSerializer.new(@user).serialized_json
set_access_token!(@user) # レスポンスヘッダーにAccessTokenを付与
render json: json_string
else
render_400(nil, @user.errors.full_messages)
終わりに
これでRails-APIでもログイン認証機能ができました。
参考
ActionController::HttpAuthentication::Token
HTTP Token authentication Simple Token example class PostsController < ApplicationController TOKEN = "secret" before_action :authenticate, except: de...

【Ruby入門】private と protected の使い方まとめ【メソッドのアクセス制御】
クラスの中で定義できるメソッドは、外から直接 呼び出せないようにアクセス制御を設定することができます。 以下か ...

Bearer認証について - Qiita
HTTP上で認証を行う場合, セッションによる認証 リクエストボディにトークンを含める認証 独自ヘッダにトークンを含める認証 Authorizationヘッダを用いた認証(Basic, Digest, Bearer) JWT認証 ...

Rubyの@_って何?? - Qiita
@_って何だろう... gem等を読んでると、 @_ を時々見るけど、@とは違うのかな? と思い、調べてみました。 def config @_config ||= Config.new end ...
コメント