前提・実現したいこと
Ruby on RailsとSwiftUIで以下のようなログイン機構を実装しております。
Rails側でデバッグするとログイン処理中はcurrent_userが取得できますが
違う部分でAPIを叩くとcurrent_userがnilになってしまいます。
ログイン処理は正確に動きますが、ログアウト処理の部分が動きません。
ログアウトの場合も.deleteでAPIにリクエストを送りたいのですが、そのためには上記のログイン処理中にSwift側でもcurrent_userを保持しておく必要があると思いますが、どのような処理を実装してログアウトの.deleteでAPIではどのようなパラメータを送れば良いでしょうか?
ruby
1routes.rb 2post '/login', to: 'sessions#create' # ログイン 3delete '/logout', to: 'sessions#destroy' # ログアウト
Ruby
1helper/session_helper.rb 2module SessionsHelper 3 # 渡されたユーザーでログインする 4 def log_in(user) 5 session[:user_id] = user.id 6 end 7 8# 現在ログイン中のユーザーを返す 9 def current_user 10 if session[:user_id] 11 @current_user ||= User.find_by(id: session[:user_id]) 12 end 13 end 14 15#受け取ったユーザーがログイン中のユーザーと一致すればtrueを返す 16 def current_user?(user) 17 user == current_user 18 end 19 20# ユーザーがログインしていればtrue、その他ならfalseを返す 21 def logged_in? 22 !current_user.nil? 23 end 24 25# 現在のユーザーをログアウトする 26 def log_out 27 session.delete(:user_id) 28 @current_user = nil 29 end 30end
ruby
1controllers/sessions_controller.rb 2 3class SessionsController < ApplicationController 4 # ログイン処理 http://127.0.0.1:3000/login.json 5 def create 6 user = User.find_by(email: params[:session][:email].downcase) 7 if user && user.authenticate(params[:session][:password]) 8 log_in user 9 render json: { status: 'SUCCESS LOGIN', user: user } 10 else 11 render json: { status: 'SUCCESS FAILD', user: user } 12 end 13 end 14 15 # ログアウト処理 http://127.0.0.1:3000/logout.json 16 def destroy 17 log_out if logged_in? <- Swift側からAPIを叩くとここでcurrent_userがnilになる(swift側でcurrent_userの値を保持できていない) 18 redirect_to root_url 19 end 20end
Swift側は以下のようになっております。
Swift
1ContentView.swift 2 3import SwiftUI 4import Alamofire 5 6class AppState: ObservableObject { 7 @Published var isLogin = false 8} 9 10struct ContentView: View { 11 @State private var email: String = "" 12 @State private var password: String = "" 13 14 @EnvironmentObject var appState: AppState 15 16 var body: some View { 17 NavigationView { 18 VStack { 19 20 NavigationLink(destination: HomeView(), isActive: self.$appState.isLogin) { 21 EmptyView() 22 } 23 24 TextField("メールアドレス", text: $email) 25 TextField("パスワード", text: $password) 26 Button(action: { 27 28 let parameters = [ 29 "user": [ 30 "email": self.email, 31 "password": self.password 32 ] 33 ] 34 35 AF.request("http://127.0.0.1:3000/login.json", 36 method: .post, 37 parameters: parameters, 38 encoder: JSONParameterEncoder.default) 39 .validate(contentType: ["application/json"]) 40 .responseJSON { response in 41 if response.response?.statusCode == 200 { 42 if let json = response.value as? NSDictionary { 43 print(json) 44 if json["status"] as? String == "SUCCESS LOGIN" { 45 self.appState.isLogin = true 46 debugPrint(response) 47 print("SUCCESS LOGIN") 48 } else if json["status"] as? String == "INVALID" { 49 debugPrint(response) 50 print("IN ¥VALID") 51 } 52 } 53 } 54 } 55 }, label: { 56 Text("ログインする") 57 }) 58 }.padding() 59 } 60 } 61} 62 63 64struct HomeView: View { 65 @EnvironmentObject var appState: AppState 66 var body: some View { 67 if appState.isLogin == false { 68 ContentView().environmentObject(AppState()) 69 } 70 VStack { 71 Text("ホーム画面") 72 73 Button(action: { 74 75 let parameters = [ <- ここのパラメータにどのような値をセットすればよいか分からないため、.delete(ログアウト処理)は失敗する 76 "": "" 77 ] 78 79 AF.request("http://127.0.0.1:3000/logout.json", 80 method: .delete, 81 parameters: parameters, 82 encoder: JSONParameterEncoder.default) 83 .validate(contentType: ["application/json"]) 84 .responseJSON { response in 85 debugPrint(response) 86 } 87 self.appState.isLogin = false 88 }, label: { 89 Text("ログアウトする") 90 }) 91 } 92 .navigationBarBackButtonHidden(true) 93 .navigationBarHidden(true) 94 } 95}
コードの部分が長くなりましたが、是非アドバイスなどよろしくお願い致します。
あなたの回答
tips
プレビュー