Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
137
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

【Rails】RailsでAPIの簡単なトークン認証を実装する

準備

Rails 5のAPI modeでRails newする。

rails new apiTokenAuthentication --api -d postgresql

scaffoldする。てきとうなAPIを作る。

bundle exec rails g scaffold Product name:string age:integer email:string
bundle exec rake db:setup
bundle exec rake db:migrate

動作確認

$ curl -X POST -H 'Content-Type:application/json' -d '{ "name": "test", "price": 500 }' http://0.0.0.0:3000/products
$ curl -X GET -H 'Content-Type:application/json' http://0.0.0.0:3000/products | jq . 

[
  {
    "updated_at": "2016-09-14T17:54:24.717Z",
    "created_at": "2016-09-14T17:54:24.717Z",
    "price": 500,
    "name": "test",
    "id": 1
  }
]

トークン認証

authenticate_or_request_with_http_tokenを使う

authenticate_or_request_with_http_tokenにブロックを渡してトークンをチェックする。

app/controllers/application_controller.rb
class ApplicationController < ActionController::API
  include ActionController::HttpAuthentication::Token::ControllerMethods

  before_action :authenticate

  protected
  def authenticate
    authenticate_or_request_with_http_token do |token, options|
      token == 'FOO'
    end
  end
end

動作確認。AuthorizationヘッダーにAuthorization: Token FOOAuthorization: Bearer FOOがない場合は、HTTP Token: Access denied.を返すようになった。

$ curl -X GET -H 'Authorization: Token BAR' -H 'Content-Type:application/json' http://0.0.0.0:3000/products/1
HTTP Token: Access denied.

$ curl -X GET -H 'Authorization: Token FOO' -H 'Content-Type:application/json' http://0.0.0.0:3000/products/1 | jq .
{
  "updated_at": "2016-09-14T17:54:24.717Z",
  "created_at": "2016-09-14T17:54:24.717Z",
  "price": 500,
  "name": "test",
  "id": 1
}

authenticate_with_http_tokenを使う

authenticate_with_http_tokenにブロックを渡してトークンをチェックする。
authenticate_or_request_with_http_tokenと違ってレスポンスを返す処理は自分で実装する。

app/controllers/application_controller.rb
class ApplicationController < ActionController::API
  include ActionController::HttpAuthentication::Token::ControllerMethods

  before_action :authenticate

  protected
  def authenticate
    authenticate_token || render_unauthorized
  end

  def authenticate_token
    authenticate_with_http_token do |token, options|
      token == 'FOO'
    end
  end

  def render_unauthorized
    # render_errors(:unauthorized, ['invalid token'])
    obj = { message: 'token invalid' }
    render json: obj, status: :unauthorized
  end
end

動作確認。

$ curl -X GET -H 'Authorization: Token BAR' -H 'Content-Type:application/json' http://0.0.0.0:3000/products/1 | jq .                                                                                   
{
  "message": "token invalid"
}

まとめ

method
authenticate_with_http_token トークンとオプションを受け取るブロックを渡してToken認証する。レスポンスは自分で書く。
request_http_token_authentication 中でauthenticate_with_http_tokenを使っていて、ブロックを渡すところまでは一緒。こちらは簡単なテキストのレスポンスを返すところまでやってくれるのでレスポンスの処理を書く必要がない。

注意

Rail5ではAuthorization: Token xxx, Authorization: Bearer xxxのようにTokenでもBearerでもどちらでもいける。
Rail4の場合は、Tokenの方しか使えないので注意。

参考

Rails5 APIモード

トークン認証

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
137
Help us understand the problem. What are the problem?