public function authorize()
{
$id = $this->route('id');
.....
}
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.
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);
Or :
$id = $this->id;
Using and Id in the URL isn't the safest way. Suggest using the username, or I generate a radon string on user creation.
Use $this->id in the request will solve your problem.
function authorize()
{
return ( Auth::user()->id == $this->id ) || Auth::user()->is_admin();
}
Curious about why it's not safe. If the Authorize method is well designed, theres no danger in this.
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.
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.
@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;
}
}
Please or to participate in this conversation.