やりたいこと
laravelでpolicyを使った認可処理でつまづいています。
投稿(create)した本人しか更新できない(update)ようにしたいのですが、誰でも更新できるような状態になってしまいます。他の質問者様の内容や記事も参考にしましたが、どうもうまくいっていない状況です。アドバイス等いただければ嬉しいです。
やってみたこと
主に公式ドキュメントを参考にpolicyを作成しています。
ポリシーの生成
ポリシー名はモデル名と同じにするよう、contactFormPolicyとしました。
PHP:app/Policies/ContactFormPolicy.php
1 /** 2 * Determine whether the user can update the model. 3 * 4 * @param \App\Models\User $user 5 * @param \App\Models\ContactForm $contactForm 6 * @return \Illuminate\Auth\Access\Response|bool 7 */ 8 public function update(User $user, ContactForm $contactForm) 9 { 10 return $user->id === $contactForm->user_id; 11 } 12
ポリシーの登録
PHP:app/Providers/AuthServiceProvider.php
1namespace App\Providers; 2 3// use Illuminate\Support\Facades\Gate; 4 5use App\Models\ContactForm; 6use App\Policies\ContactFormPolicy; 7use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; 8 9class AuthServiceProvider extends ServiceProvider 10{ 11 /** 12 * The model to policy mappings for the application. 13 * 14 * @var array<class-string, class-string> 15 */ 16 protected $policies = [ 17 // モデル名 => モデルポリシー名 18 ContactForm::class => ContactFormPolicy::class 19 ]; 20 21 /** 22 * Register any authentication / authorization services. 23 * 24 * @return void 25 */ 26 public function boot() 27 { 28 $this->registerPolicies(); 29 30 // 31 } 32}
アクション認可
contactFormコントローラーのupdateメソッドにauthorizeメソッドを使用して、投稿(create)した同一ユーザーのみ編集(update)できるようにしたつもりです。
PHP:
1 /** 2 * Update the specified resource in storage. 3 * 4 * @param \Illuminate\Http\Request $request 5 * @param int $id 6 * @return \Illuminate\Http\Response 7 */ 8 public function update(Request $request, $id, ContactForm $contactForm) 9 { 10 $contact = ContactForm::find($id); 11 $contact->name = $request->your_name; 12 $contact->title = $request->title; 13 $contact->email = $request->email; 14 $contact->url = $request->url; 15 $contact->gender = $request->gender; 16 $contact->age = $request->age; 17 $contact->contact = $request->contact; 18 $this->authorize('update', $contactForm); //←ここにアクション処理の認可設定 19 $contact->save(); 20 return redirect() 21 ->route('contact.index'); 22 }
結果
考えたこと・思ったこと
今回はuserとcontactformを1対多の関係でリレーションし、ダミーデーターを入れて動かしています。
policy自体は動いてくれてるので、idと紐づいていない可能性があると思っていますがsqlにもデータが入っているので自分でおかしいポイントを把握できていません。
ER図
sql(カラム)
sql(データ)
よろしくお願いします。
ルーティング
PHP:routes/web.php
1Route::group(['prefix'=>'contact','middleware'=>'auth'], function(){ 2 Route::get('index', [ContactFormController::class ,'index'])->name('contact.index'); 3 Route::get('create', [ContactFormController::class ,'create'])->name('contact.create'); 4 Route::post('store', [ContactFormController::class ,'store'])->name('contact.store'); 5 Route::get('show/{id}/', [ContactFormController::class, 'show'])->name('contact.show'); 6 Route::get('edit/{id}/', [ContactFormController::class, 'edit'])->name('contact.edit'); 7 Route::post('update/{id}/', [ContactFormController::class, 'update'])->name('contact.update'); 8 Route::post('destroy/{id}/', [ContactFormController::class, 'destroy'])->name('contact.destroy'); 9 });
解決
アドバイスをもとに下記修正したところ、想定通りの動きができました。
ルーティング
アクションを全て記載していたので、resourcesに変更してコードをスッキリしました。
PHP:routes/web.php
1Route::group(['middleware'=>'auth'], function(){ 2 Route::resource('contact', ContactFormController::class, 3);
コントローラーの記載
こちらの記事を参考にフィルを使う場合の記載に変更しました。結局authorizeを使用した方法しか今はわかりませんでしたが、authorizeの第二引数の使い方が良くないことは理解できました。またルーティングをresourceにすると、updateメソッドで$idを使用しないと値をとれませんでした。
ただ、これで投稿ユーザーしか編集ができないように設定することができました!
fillを使ったカラムの登録
PHP
1 public function update(Request $request, $id) 2 { 3 4 $contact = ContactForm::find($id); 5 $this->authorize('update', $contact); //authorizeを使用した認可 6 $contact->fill([ 7 'name' => $request->your_name, 8 'title' => $request->title, 9 'email' => $request->email, 10 'url' => $request->url, 11 'gender' => $request->gender, 12 'age' => $request->age, 13 'contact' => $request->contact, 14 ]); 15 $contact->save(); 16 return redirect() 17 ->route('contact.index');

回答1件
あなたの回答
tips
プレビュー
下記のような回答は推奨されていません。
このような回答には修正を依頼しましょう。
また依頼した内容が修正された場合は、修正依頼を取り消すようにしましょう。
2022/08/07 09:02
2022/08/07 12:31 編集
2022/08/07 16:27