基本的な使い方だが、記録としておく。
##要件:
1.ユーザー自身で自分のプロフィールのみ編集することはできる。
2.ゲストとユーザーが他人のプロフィールを閲覧することのみ、許可される。
###まず、要件②はミドルウェアの追加で満たすことはできる。
ゲストは「.../user/5/edit」にアクセスしたらログインページにリダイレクトする仕組みになっている。
class UsersController extends Controller
{
//プロフィールを閲覧すること以外の動作は認証済のユーザーのみ行われる
public function __construct()
{
$this->middleware('auth',['except'=>['show']]);
}
public function show(User $user)
{
return view('users.show',compact('user'));
}
public function edit(User $user)
{
return view('users.edit',compact('user'));
}
public function update(UserRequest $userRequest,ImageUploadHandler $uploader,User $user)
{
$data = $userRequest ->all();
if($userRequest->avatar){
$result = $uploader->save($userRequest->avatar,'avatars',$user->id,env('UPLOAD_SIZE'));
if($result){
$data['avatar'] = $result['path'];
}
}
$user->update($data);
return redirect()->route('users.show',$user->id)
->with('success','プロフィールを更新しました!');
}
}
###次の要件①に、本人以外のプロフィール操作を防ぐために、laravelのポリシーを使用します。
//ポリシーを生成
php artisan make:policy UserPolicy
作成されたユーザーポリシーに下記で記述
<?php
namespace App\Policies;
use App\Models\User;
use Illuminate\Auth\Access\HandlesAuthorization;
class UserPolicy
{
use HandlesAuthorization;
/**
* ユーザー本人が更新可能か決める
* @param User $currentUser
* @param User $user
* @return bool
*/
public function update(User $currentUser,User $user)
{
return $currentUser->id === $user->id;
}
}
次に、ポリシーを登録する。Userモデルは「app」配下でない場合、下記でモデルの設定します。
<?php
namespace App\Providers;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
// 'App\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
// 'App\Model\User' => 'App\Policies\UserPolicy',
Gate::guessPolicyNamesUsing(function ($modelClass){
return 'App\Policies\\'.class_basename($modelClass).'Policy';
});
}
}
最後にコントローラヘルパによる認可を設定する
UserControllerに、「edit」「update」メソッドに下記のラインを追加。
$this->authorize('update', $user);
アクションが認可されない場合、authorizeメソッドはIlluminate\Auth\Access\AuthorizationException例外を投げ、これはデフォルトでLaravelの例外ハンドラにより、403ステータスコードのHTTPレスポンスへ変換されます。
<?php
namespace App\Http\Controllers;
use App\Handlers\ImageUploadHandler;
use App\Http\Requests\UserRequest;
use App\Models\User;
use Illuminate\Http\Request;
class UsersController extends Controller
{
public function __construct()
{
$this->middleware('auth',['except'=>['show']]);
}
public function show(User $user)
{
return view('users.show',compact('user'));
}
public function edit(User $user)
{
$this->authorize('update',$user);
return view('users.edit',compact('user'));
}
public function update(UserRequest $userRequest,ImageUploadHandler $uploader,User $user)
{
$this->authorize('update',$user);
$data = $userRequest ->all();
if($userRequest->avatar){
$result = $uploader->save($userRequest->avatar,'avatars',$user->id,env('UPLOAD_SIZE'));
if($result){
$data['avatar'] = $result['path'];
}
}
$user->update($data);
return redirect()->route('users.show',$user->id)
->with('success','プロフィールを更新しました!');
}
}