2017-04-14 4 views
1

すべてが正常に動作しているLaravelネストされたリソースのセキュリティ

route()->resources('user', 'UserController'); 
route()->resources('user.place', 'PostController'); 
route()->resources('user.place.picture', 'PictureController'); 

、私はこのようなリソースを入れ子にしている、私はなど、各時間に沿ってユーザーのIDを渡します...

あなたが場所に来るときは、これがあなたのものなら、私は編集していくつかの行動をとるためのボタンを表示します。だから私は$place.user_id == $user.idボタンを表示するかどうかを確認します。 Place.showため/user/1/place/2

例えば、私は、次のURLを持っている私の場所にアクセスするためにあるため、少しプレイした後。ボタンが表示されて

は、私が所有者だと私は変更することができますが、別のユーザー(例えばUSER_ID 2)は私の場所を見て、同じURLを使用するならば、彼は何も変更することはできませんが、場所を見ることができます。私が見つけた何

は、このユーザーが同じURLを使用するが、その後採掘するのuser_idを変更した場合、彼は場所へのフルアクセスを持って、それを修正することができるということです。この動作を防止するための解決策があった場合、私はネストされたリソースのすべてのメソッドを保護する必要がある場合、それは長くなってきているため Auth::user()->id == $user->id

私は思ったんだけど何を、次のとおりです。

だからこれから保護するために、私は別の条件を追加しました実装するのが醜い。また、私は次のレベルに来るときuser.place.picture。私が降りるたびに別のセキュリティ層を追加する必要があると思う。 $picture->place_id == $place->idなど。だから、

、ユーザーが何も防ぐないか1つのIDが変更されたかどうかをチェック右ユーザー、場所、写真IDでそれをクリックすることができますので、私はリンクを印刷します。最後のものが変更されている場合は、別の要素を取得するので問題ありません。しかし、私たちが親のIDを変更すると、特に私が途中でアクセスを許可すると、危険になる可能性があります。

私が逃した簡単な解決策がありますように!

+0

ポリシー(https://laravel.com/docs/5.4/authorization)をご確認ください。 – Robert

答えて

2

まず、このチェックを実行する必要はありません。

$place.user_id == $user.id

あなたが発見したとして、URLから派生し$userを簡単に操作することができるので、そのガードには値がありませんので。あなたがそれらの両方を必要としない、あなたはPlaceの所有者である現在Userログインを確認するにチェックを追加しましたが、それはあなただけのチェックをする必要があります。

私が正しく理解していれば、これはPolicies in Laravelを使用するための完璧なユースケースのように聞こえます。ドキュメントは非常に包括的ですが、具体的な使用例については試してみます:

  • Policyを生成してください。PlacePolicyあなたのユースケースについては
  • 、このポリシーでは、パラメータとして受け入れupdate()方法を、作成しUser(ユーザーログイン)とPlace
  • update()方法(場所は、彼らがアクセスしようとしています) PlacePolicyは今UserだからPlace

を更新することができれば、それはこのように見えるかもしれませんが、何らかの手段によって、決定することができます。

<?php 

namespace App\Policies; 

use App\Place; 
use App\User; 

class PlacePolicy 
{ 
    /** 
    * Determine if the given place can be updated by the User. 
    * 
    * @param \App\User $user 
    * @param \App\Place $place 
    * @return bool 
    */ 
    public function update(User $user, Place $place) 
    { 
     return $place->user_id == $user->id; 
    } 
} 

これは非常に単純なチェックです - しかし、あなたは、本質的に絶対に与えられたユーザーは、別のモデルのアクションを実行できるかどうかを判断するために、ここで何を行うことができます。

注:あなたがのServiceProviderで、このポリシーを登録する必要があります、代わりにこのPolicyでこの

を行う方法で上記のリンクドキュメントを参照してください、あなたは便利なツールの配列を利用することができますLaravelは提供します。たとえば、あなたがこのような何かをするためにブレードcanディレクティブを利用することができます

@can('update', $place) 
    < SHOW THE EDIT BUTTON > 
@endcan 

ます。また、最初の場所でアクセスされているページを防止するMiddleware経由Policyクラス適用することができます。うまくいけば、この

Route::get('/user/{user}/place/{place}' .....)->middleware('can:update,place'); 

をあなたをあなたの道に導くのに十分です! :)

関連する問題