RailsとVue.jsを合わせたアプリを作っているのですが、ログイン周りはdeviseを用いており、APIを叩く方法を模索していたのでアウトプットとして記事をまとめます。
目次
目的
deviseの非同期ログイン機能を実装
(前提、環境)
mac
macOS Mojave 10.14.5
ruby 2.5.1
rails 5.2.3
はじめに
この記事ではRails側だけでAPIを叩いてviewをだす実装方法です。
参考記事
Devise – Sign In with Ajax
Rails5 API + devise でユーザーの認証と作成機能を実装した API を作成する
導入手順
devise用のコントローラーを作成
# ターミナル
rails g devise:controllers
routes.rbにパスを追記
# config/routes.rb
devise_for :users, controllers: {
sessions: 'users/sessions'
}
sessions_controllerのアクションを定義
# app/controllers/users/sessions_controller.rb
def create
resource = User.find_for_database_authentication(email: params[:user][:email])
return invalid_login_attempt unless resource
if resource.valid_password?(params[:user][:password])
sign_in :user, resource
return render nothing: true
end
invalid_login_attempt
end
protected
def invalid_login_attempt
set_flash_message(:alert, :invalid)
render json: flash[:alert], status: 401
end
devise.rbの設定を追記
# config/initializers/devise.rb
config.http_authenticatable_on_xhr = false
config.navigational_formats = ["*/*", :html, :json]
devese.ja.ymlのinvalidメッセージを追記
# config/locales/devise.ja.yml
sessions:
already_signed_out: 既にログアウト済みです。
new:
sign_in: ログイン
signed_in: ログインしました。
signed_out: ログアウトしました。
invalid: 無効なemailまたはpasswordです。
view側を非同期通信で送る準備
= form_for resource, url: session_path(:user), remote: true do |f|
= f.text_field :email
= f.password_field :password
= f.label :remember_me do
Remember me
= f.check_box :remember_me
= f.submit value: 'Sign in'
:javascript
$(document).ready(function() {
//form id
$('#new_user')
.bind('ajax:success', function(evt, data, status, xhr) {
//function called on status: 200 (for ex.)
console.log('success');
})
.bind("ajax:error", function(evt, xhr, status, error) {
//function called on status: 401 or 500 (for ex.)
console.log(xhr.responseText);
});
});
終わりに
これで基本的なAPIは叩けるらしいです。
自分で書いてみるとダブルレンダリングされていたりとエラーが吐かれました。invalid_login_attemptあたりが怪しそうなので、ちょっとVue.js用にカスタマイズが必要そうです汗