Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

準備

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モード

http://morizyun.github.io/blog/rails-api-5.0.0.beta.2/

https://www.hommax39.com/archives/170

http://totutotu.hatenablog.com/entry/2015/12/19/093944

トークン認証

http://sourcey.com/building-the-prefect-rails-5-api-only-app/#versioning-your-api

https://www.codeschool.com/blog/2014/02/03/token-based-authentication-rails/

http://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token.html

http://techblog.thescore.com/2014/06/25/http-basic-authentication-and-http-token-authentication/

http://security.stackexchange.com/questions/108662/why-is-bearer-required-before-the-token-in-authorization-header-in-a-http-re

http://qiita.com/uasi/items/cfb60588daa18c2ec6f5

http://edgeapi.rubyonrails.org/classes/ActionController/HttpAuthentication/Token.html

http://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token/ControllerMethods.html#method-i-authenticate_with_http_token

Yarimizu14
メモ
abeja
「ディープラーニング」を活用し、多様な業界、シーンにおけるビジネスの効率化・自動化を促進するベンチャー企業です。
https://abejainc.com
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
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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
ユーザーは見つかりませんでした