LoginSignup
10
9

More than 5 years have passed since last update.

knockでRails5.2のAPIモードにユーザ認証を追加する

Last updated at Posted at 2018-05-15

はじめに

knockというJWT認証のGemを使ってRails5.2のAPIモードで構築したWebAPIにユーザ認証を付けてみます。

準備

てことで、とりあえずknockをbundle installして、完了したらRailsにインストールします。

rails g knock:install

これでconfig/initializers/knock.rbが生成されてるはず。

knockはAuth0っていうユーザ認証サービス?に対応しているらしいんですけど、
今回はUserモデルを用意して認証情報は自前で管理します。
下記コマンドでUserリソースで認証するためのコントローラを生成します。

$ rails g knock:token_controller user

app/controllers/user_token_controller.rbっていうコントローラが生成されてると思います。
ついでにconfig/routes.rbに生成したコントローラに対するルーティングも追加されます。
これで必要なファイルは揃ったので実装していきましょう。

実装

まずUserモデルのマイグレーションを作成。

db/migrate/yyyymmddhhiiss_create_users.rb
class CreateUsers < ActiveRecord::Migration[5.2]
  def change
    create_table :users do |t|
      t.string :email
      t.string :password_digest

      t.timestamps
    end
    add_index :users, :email, unique: true
  end
end

サクッとマイグレーションしましょう。

$ rails db:migrate

次にUserモデルにhas_secure_passwordメソッドを追加します。

app/user.rb
class User < ApplicationRecord
  has_secure_password
end

最後にapplication_controllerにknockの認証モジュールをインクルード。

app/application_controller.rb
class ApplicationController < ActionController::API
  include Knock::Authenticable
end

動作確認

適当なユーザを作ってHTTPクライアントからconfig/routes.rbに追加されたルートに、

POST /user_token
{"auth": {"email": "作成したユーザのメールアドレス", "password": "作成したユーザのパスワード"}}

を送信するとステータスコード201と共にJWTトークンが返ってくる。

はずなんだけど…

上手くいきませんでした、TypeErrorが返ってきます。
GitHubを調べてたら似たようなIssueを見つけました。
https://github.com/nsarno/knock/issues/205

どうやらRails.application.secrets.secret_key_baseはRails5.2以降はnilを返すようで、
config/initializers/knock.rbconfig.token_secret_signature_keyを変更する必要があるようです。
てことで下記のように変更しました。

config/initializers/knock.rb
## Signature key
## -------------
##
## Configure the key used to sign tokens.
##
## Default:
# config.token_secret_signature_key = -> { Rails.application.secrets.secret_key_base }
# 以下を追加
config.token_secret_signature_key = -> { Rails.application.credentials.read }

これでちゃんとJWTトークンが返ってくるようになりました。
あとは認証が必要なコントローラにbefore_action :autheticate_userを追記すれば
認証されていないリクエストはステータスコード401が返ってくるようになります。

10
9
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
10
9