AO's avatar
Level 1

Protect user settings from being access by other users

Hello,

I made this middleware to protect "user settings " from being access by other auth users.

   public function handle($request, Closure $next)
    {
         if ($request->slug != auth()->user()->slug) {
            return redirect()->to('/');
        }
        return $next($request);
    }

And I'm using vueJs to update the profile

I managed to get the slug to pass it to my url :

Route::put('/profile/{slug}','ProfilePrivateController@update');
  axios.put(`/api/profile/${this.data}`)

I used props to get my slug.

so the problem is when I ever use this route it says 401 or 500 error in the console:.

am I doing this wrong?

how I can solve this problem so VUEJS can match the request URL with the auth user (Like in the middleware)?

0 likes
18 replies
Norbertho's avatar

Usually i even use this to protect the route

Route::put('/profile/{slug}','ProfilePrivateController@update')->middleware(['auth']);
Norbertho's avatar

Have you send the CSRF token as well with the axios post?

D9705996's avatar

You can use Gates/Policies for this

https://laravel.com/docs/5.7/authorization

If you go with policies you can do

php artisan make:policy ProfilePolicy --model Profile

Then in AuthServiceProvider add

    use App\Profile;
    use App\Policies\ProfilePolicy;

    ...

    protected $policies = [
        Profile::class => ProfilePolicy::class,
    ];

In your ProfilePolicy you will have a function called

    public function view(User $user, Profile $profile)
    {
        return $user->slug === $profile->slug;
    }

Remove the middleware you added and test. You might need to tweak to match you environment but should work.

2 likes
Norbertho's avatar

can you show how do you pass the slug data in to the view? do you do something like this?

    <vue-component :slug={{ $user->slug }}></vue-component>

for me the only way it works if I pass pass in the $user->id $user->slug did not work for some reason form me

D9705996's avatar

Do you have a slug attribute on you User model/migration?

$user->slug did not work for some reason form me

Can you be more specific?

1 like
AO's avatar
Level 1

@Norbertho I tried both id and slug not working And yes I'm sending the csrf-token

<profile-section1 data="{{$user->slug}}" ></profile-section1>

still getting this response :

message: "Unauthenticated."
D9705996's avatar

Can you show your ProfilePrivateController? If you are using route model binding to find your model via slug you will need to add the following to your model as it defaults to id

public function getRouteKeyName()
{
    return 'slug';
}

Also how are you authenticating your users? Sessions, passport, etc

1 like
AO's avatar
Level 1

@D9705996 I'm using the default laravel auth

these two methods from PrivateProfileController


public function show($id)
  {
       $user = User::findBySlugOrFail($id);
     
       return response()->json($user);
  }

public function update(Request $request, $id)
  {
      $user = User::findBySlug($id);
      $user->update([
          'email'=>$request->email,
          'education_level'=>$request->education_level,
          'field'=>$request->field,
          
      ]);


      if($request->has('password')){
          $user->save([
              'password'=>$request->password
          ]);
      }

      return response()->json('user updated',200);

     
  
  }
D9705996's avatar

If you change your route to

Route::put('/profile/{user}','ProfilePrivateController@update');

Add this to you user model

public function getRouteKeyName()
{
    return 'slug';
}

Your can then type hint your user in your update method

  public function update(Request $request, User $user)
  {

         $user->update([
          'email'=>$request->email,
          'education_level'=>$request->education_level,
          'field'=>$request->field,
          
      ]);


      if($request->has('password')){
          $user->save([
              'password'=>$request->password
          ]);
      }

      return response()->json('user updated',200);
  }

Does this change anything?

D9705996's avatar

Just noticed you have this route

Route::put('/profile/{slug}','ProfilePrivateController@update');

but are trying to hit /api/profile/...

Where you put this route web.php or api.php?

D9705996's avatar

It sounds like nothing is getting passed in the {slug} part. Can you post a screenshot of the full request from devtools

1 like
D9705996's avatar

Your s reenshot doesn't show the full request information. Can you copy and paste the full output please. You should able to just click and drag then copy and paste here.

AO's avatar
Level 1

@D9705996 Well I fixed it by using the route in web.php

I guess I will stick to web.php for now.

Norbertho's avatar

Just a guess but try this

To enable / disable cookie serialization, you may change the static serialize property of the App\Http\Middleware\EncryptCookies middleware:

/**

Indicates if cookies should be serialized.
@var bool
*/
protected static $serialize = true;

and then

php artisan cache:clear php artisan view:clear

1 like
AO's avatar
Level 1

@Norbertho I tried this as well but no luck :\ anyways thank you

Please or to participate in this conversation.