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