Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

smadeira's avatar

Accessing the id from the URL

I have this URL - example.com/users/23/edit which will display the update a user profile form for the user with id 23. That's all straight forward.

Because you can change the URL to whatever you want, what I need to do is ensure that the person editing the profile is either an admin or it is the user with ID 23. We don't want non-admins editing other profiles.

I want to do the authorization from the authorize() method in a FormRequest. What is the best way of getting the id from the URL (23 in the example)? OR, should I add the ID as a hidden field in the form so I can get to it from the Request object? Or, is there another way I should be approaching this?

Thanks for the help.

0 likes
8 replies
arabsight's avatar
public function authorize()
{
    $id = $this->route('id');

  .....
}
1 like
ghvinashvili's avatar

example.com/users/23/edit

this get users form url

Request::segment(1);

this get id 23 form url

Request::segment(2);

this get edit form url

Request::segment(3);
jekinney's avatar

Using and Id in the URL isn't the safest way. Suggest using the username, or I generate a radon string on user creation.

EliasSoares's avatar

Use $this->id in the request will solve your problem.

function authorize()
{
   return ( Auth::user()->id == $this->id ) || Auth::user()->is_admin();
}

@jekinney

Curious about why it's not safe. If the Authorize method is well designed, theres no danger in this.

jekinney's avatar

@EliasSoares

It gives un wanted people clues into your data base schema. For example with in a minute or two I could know how many users are in your database just by typing numbers in the URL. It is also a suggestion that there might be other weaknesses so people will be looking for more.

1 like
jekinney's avatar

@EliasSoares

It gives un wanted people clues into your data base schema. For example with in a minute or two I could know how many users are in your database just by typing numbers in the URL. It is also a suggestion that there might be other weaknesses so people will be looking for more.

nolros's avatar

@smadeira if you need to use user if segments then you can create middleware and authenticate using teh users id, but then redirect them to another url, which could be a user attribute or some other attribute.

use Closure;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Routing\Redirector;
use Illuminate\Http\Request;
use Rhumsaa\Uuid\Uuid;

class UserRouterMiddleware
{

    private $segment    = null;
    private $guestPath  = 'welcome';
    /**
     * @var User
     */
    private $user;
    /**
     * @var Guard
     */
    private $auth;
    /**
     * @var Uuid
     */
    private $uuid;
    /**
     * @var Redirector
     */
    private $redirector;
    /**
     * @var Request
     */
    private $request;


    /**
     * @param User $user
     * @param Guard $auth
     * @param Uuid $uuid
     * @param Redirector $redirector
     * @param Request $request
     */
    function __construct(User $user, Guard $auth, Uuid $uuid, Redirector $redirector, Request $request)
    {
        $this->user = $user;
        $this->auth = $auth;
        $this->uuid = $uuid;
        $this->redirector = $redirector;
        $this->request = $request;
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {

        $this->setSegment($request->segments(2));

        if ($this->auth->guest())
        {
            $this->userOfSegment()->redirectTo();
        }

        if ($this->auth->user()->getAuthIdentifier() === $this->segment)
        {
            $this->userOfAuth()->redirectTo();
        }

        if (isset($this->segment))
        {
            $segments       = $request->segments();
            $segments[2]    = $this->segment;

            $newUrl = implode('/', $segments);

            if (array_key_exists('QUERY_STRING', $_SERVER)) $newUrl .= '?' . $_SERVER['QUERY_STRING'];

            return $this->redirector->to($newUrl);
            
        }
        
        return $next($request);
    }
    
    /**
     * Set the path to segment 2 that will be used for redirecting. This could be
     * uuid or id, or generic string
     */
    private function redirectTo()
    {
        if ($this->user->exists && $this->user instanceof User)
        {
            $this->setSegment($this->user->uuid); // or any other generic path or user attribute
        }
        else
        {
            $this->setSegment($this->guestPath); 
        }
    }

    /**
     * Return true if segment 2 is numeric and can therefore be used for find
     * 
     * @return bool
     */
    private function isSegmentNumeric()
    {
        if (isset($this->segment) && ! is_numeric($this->segment)) return true;

        return false;
    }

    /**
     * Set the user from auth user
     * 
     * @return $this
     */
    private function userOfAuth()
    {
        if ($this->auth->check())
        {
            $this->user = $this->auth->user();
        }

        return $this;
    }

    /**
     * Retrieve the user using the id if the user is not auth
     * 
     * @return $this
     */
    private function userOfSegment()
    {
        if ($this->isSegmentNumeric())
        {
            $this->user = $this->user->find(intval($this->segment));
        }
        return $this;
    }

    /**
     * @param $segment
     */
    private function setSegment($segment)
    {
        $this->segment = $segment;
    }

}
1 like

Please or to participate in this conversation.