Protect user settings from being access by other users

Published 1 week ago by AO-IO

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}','[email protected]');
  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)?

Norbertho

Usually i even use this to protect the route

Route::put('/profile/{slug}','[email protected]')->middleware(['auth']);
AO-IO

@Norbertho well any auth user can access others settings :\

Norbertho

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

D9705996
D9705996
1 week ago (127,290 XP)

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.

Norbertho

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
D9705996
1 week ago (127,290 XP)

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?

AO-IO

@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
D9705996
1 week ago (127,290 XP)

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

AO-IO

@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
D9705996
1 week ago (127,290 XP)

If you change your route to

Route::put('/profile/{user}','[email protected]');

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
D9705996
1 week ago (127,290 XP)

Just noticed you have this route

Route::put('/profile/{slug}','[email protected]');

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

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

AO-IO

@D970 now I get 405 error .. I was getting 401

http://prntscr.com/l50e83 http://prntscr.com/l50eel

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

yes in api.php

axios.put(`/api/profile/${this.data})
D9705996
D9705996
1 week ago (127,290 XP)

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

AO-IO

this is the request error 401 :

http://prntscr.com/l51ewq

request headers :

http://prntscr.com/l51f6j

Response :

http://prntscr.com/l51fdr

the slug is being passed without problems but it keeps saying not auth! (the token is passed tho)

D9705996
D9705996
1 week ago (127,290 XP)

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.

Please sign in or create an account to participate in this conversation.