3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【初心者向け】RailsでAPI開発 Part.2

Posted at

これは何?

【初心者向け】RailsでAPI開発 Part.1
の続きです。

今回は認証編となります。

概要

▼ 仕組み

認証については、下記のように判定するものとする。

  1. emailとpasswordが入力される。
  2. 登録が完了したらトークンを発行してクライアントに返す。
  3. クライアントは毎リクエスト、トークンをヘッダーに入れてリクエストを送る。

▼ 使用するもの

  • has_secure_password
    • bcrypt(事前に追加しておいてください。)
  • has_secure_token
    • ActionController::HttpAuthentication::Token
      • authenticate_with_http_token

手順

① UserModelを整える

- name:string
- email:string
- password_digest:string
- token:token
addp/models/user.rb
before_save { self.email = self.email.downcase }
has_many :books
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 }, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false }
has_secure_password
validates :password, presence: true, length: { minimum: 6 }
has_secure_token

上記のように設定することで、
バリデーションはもとより、Userが作成されると自動的に、

  • セキュアなパスワードがDBに保存
  • セキュアなトークンがDBに保存
    されていく。

② UserControllerを整える

app/controllers/v1/users_controller.rb
before_action :set_user, only: [:show]

def show
 render json: @user, adapter: :json
end

def create
 user = User.new(user_params)
 if user.save
  render json: user, adapter: :json, status: 201
 else
  render json: { error: user.errors }, status: 422
 end
end

private
def set_user
 @user = User.find(params[:id])
end

def user_params
 params.require(:user).permit(:name, :email, :password, :token)
end

③ トークン認証

app/controllers/application_controller.rb
include ActionController::HttpAuthentication::Token::ControllerMethods

rescue_from ActiveRecord::RecordNotFound, with: :record_not_found

def authenticate
 authenticate_with_http_token do |token, options|
  @current_user = User.find_by(token: token)
  @current_user != nil ? true : render_unauthorized_request
 end
end

def render_unauthorized_request
 self.headers['WWW-Authenticate'] = 'Token realm="Application"'
 render json: { error: 'No Authentication' }, status: 401
end

def record_not_found
 render json: { error: 'Record not Found' }, status: 404
end

④ 認証が必要なページに設定

app/controllers/v1/users_controller.rb
..
before_action :authenticate, except: [:create]
..

まとめ

難易度の高いと思われていた認証も、
Railsの標準の機能でかなり簡単に実装できることがわかりました。

まずはサービスに登録させ、そのタイミングでトークンを発行してクライアントに送ってあげれば、
あとはヘッダーのトークン情報に合わせて認証しているかを判断しているだけです。
それをリクエスト毎に判断してあげるというシンプルな構造です。

次はPunditを使って認可周りを整えていきます。
ここまではサービスに登録しているかどうかだけの判断でしたが、
認可を作り込むことで、自分の情報だけは編集できるようにするなどのことができるようになります。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?