Home > Blockchain >  Laravel issue with security in profile page
Laravel issue with security in profile page

Time:10-02

I have been having problems with my site in Laravel for some time. I have an Angular frontend and I'm using an api to query the specific user's data so that a specific user can change his data in his profile page. With that said, I obviously don't want unauthorized people to be able to go to other profile pages to change their data as well.

For example: On my page, with the URL .../user/1 the user can query his data. The problem with this is: If you change the 1 in .../user/1 to .../user/2 for example, the person can access to the data of the person with id 2.

I tried following: In my api.php:

Route::middleware('auth:api')->get('/user', function (Request $request) {
    return $request->user();
});

// Get Specific User
Route::get('user/{id}' ,'App\Http\Controllers\UserController@getUserById')->middleware('auth');

Unauthorized users can no longer access the profile page, but all Authorized users can access all other users and change their data.

I also tried: $id = Auth::id(), but this returns me Attempt to read property "id" on null

The problem seems to me to be quite complicated, as I somehow need the id of the users currently logged in and make sure they can't access other users id. Do you have any idea how I could best do this?

I am using Laravel 8

Thanks a lot!

CodePudding user response:

Authorization can be challenging but fortunately, Laravel comes with serveral tools to help you.

One of them is policies which allows you to control who can view/store/update/delete resources (like your users).

The full documentation about authorization covers this topic very well: https://laravel.com/docs/8.x/authorization


That being said, for this specific case - the user - you could do something like auth/me that show the profile of the authenticated user (without passing the id as a parameter).

As always, there are many ways to do the same thing and in the end it all depends of your project, your experience, your goals...

CodePudding user response:

IMO, you should use /users routes in regards to users' CRUD and a /profile route for editing the user's data.

Anyway, there is a simple way to achieve what you need with middlewares. Let's say that you want to allow to use a route ONLY if the {id} parameter is the same as the authenticated user.

You can create a very basic middleware IE ResourceOwner

<?php

namespace App\Http\Middleware;

use Closure;

class ResourceOwner
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if ($request->id !== auth('api')->user->id) {
            abort(403);
        }

        return $next($request);
    }
}

The middleware will check if the incoming id parameter is the same as the user logged in, if not, abort throwing a 403 error response.

In order to use this middleware, you can add it to your route

use App\Http\Middleware\ResourceOwner;

Route::get('user/{id}' ,'App\Http\Controllers\UserController@getUserById')->middleware(['auth', 'ResourceOwner']);

Please note that auth('api')->user->id will depend on how you are authenticating your users

  • Related