準備
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 FOOかAuthorization: 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モード
トークン認証