Set username as prefix in URIs Laravel - laravel

I want to set prefix in all of the authenticated URIs in Laravel 5.3 app. If I use Route::group(['prefix' => {username}]), then how can I get the username in web.php file.

Assuming you have defined routes like this:
Route::group(['prefix' => '/{user}'], function() {
Route::get('/profile', 'UserController#showProfile')->name('user.profile');
});
You can use Laravel's route-model binding to pass an User instance directly into your routes:
View Profile
Then in the controller , you can easily grab that model instance:
class UserController extends Controller
{
public function showProfile(User $user)
{
return view('user.profile.index', compact('user'));
}
}
Check out the documentation here.
EDIT: By default, Laravel uses the id column when retrieving a given model class. You can change that to any column, in your case username , easily by overriding the getRouteKeyName() method on your User model.
public function getRouteKeyName()
{
return 'username';
}

You can't and you shouldn't hardcore routes with usernames. If you have 100 users, do you plan to create 100 route groups for each user? Assuming each user has 2 routes that's 200 routes.
What you need to do is generate routes with username segment and detect the user on the fly based on the user name.
Route::group(['prefix' => '{username}'], function () {
Route::get('profile', 'UserController#profile');
Route::get('setting', 'UserController#setting');
});
The routes generated would be like
http://example.app/{username}/profile
http://example.app/{username}/setting
So a user with username adam with get the links.
http://example.app/adam/profile
http://example.app/adam/setting
Similarly you can have username based links for all your users and you need to detect them in your controller using route model binding or the standard way.
Edit
For closure based routes you can get the url segment like so
Route::get('{username}/profile', function ($username) {
return 'Username is '.$username;
});
With controllers you get them as the parameters.
public function profile($username)
{
return $username;
}

Related

How to get User()->id in Controllers (Laravel 8+)

I am trying to select tasks by user('id'), but I can't get it in a Controller, where I selecting data from DB.
I have tried many thing and some of them from stackoverflow, but it isn't working.
I tried:
1. $userId = Auth::check() ? Auth::id() : true;
2. Auth::user()->id;
3. public function getUserId(){
on Model} - and then get this value on Controllers
and some other things
I have the simplest code:
I installed registration: npm artisan ui --auth something like that
I installed vuejs (on Laravel)
I created api on Laravel, and some logic on vue
I didn't touch "app.blade.php" it's the same as it was.
I can get data, user: name, id and all what I want in file "app.blade.php" but I need those data in folder->file: App\Http\Controllers{{SomeController}}, but I don't know how.
Was someone in this situation?
How can I get user id in Controllers?
Thanks guys for earlier.
If you need user id, just use one of this :
auth()->id();
using Auth facade's
\Auth::id();
or, using Request instance
$request->user()->id
Follow this simple controller code, i showed 3 different way here :
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class SomeController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function getUserId(Request $request)
{
$user = Auth::user(); // Retrieve the currently authenticated user...
$id = Auth::id(); // Retrieve the currently authenticated user's ID...
$user = $request->user(); // returns an instance of the authenticated user...
$id = $request->user()->id; // Retrieve the currently authenticated user's ID...
$user = auth()->user(); // Retrieve the currently authenticated user...
$id = auth()->id(); // Retrieve the currently authenticated user's ID...
}
}
Auth::user()->id;
This should work if you have Auth middleware on that controller method where you try to get it, please check do you added that middleware.
For checking you can use php arisan route:list command.
Is someone still searching an answer on this question. I have some explanation how can you do this.
Laravel has a Router which routes authorization process through that Controller which you want, so you should redirect that process on your Router and in Controller create constructor which allows you to take user id.
How can you do that?:
1. First of all you should find Controller and Route which responsible for authorization and registration users.
In my case it was:
a)App\Http\Controllers\HomeController
b)routes\web.php
2. Second, you should redirect your authorization Router to the Controller where you trying to get Auth::id();
In my case it was:
App\Http\Controllers\TasksController
so, in routes\web.php I did this:
//was
Route::get('/', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
//was
Auth::routes();
//was
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
//added
Auth::routes();
//added
Route::get('/home', [App\Http\Controllers\TasksController::class, 'index'])->name('home');
perhaps you should have index function on that controller
3. Third you should add constructor in your controller where you want to get user id, this constructor I took from HomeController, it already was there.
In my case it was:
public function __construct()
{
$this->middleware('auth');
}
code with function on my TasksController:
public function __construct()
{
$this->middleware('auth');
}
public function index()
{
$userId = Auth::check() ? Auth::id() : true;
}
And now I can take user id.
PS: constructor I added on the top in class TasksController in Controller

Setting the route parameter in the middleware in Laravel

I am developing a Laravel application. I am doing route model binding in the middleware.
I have the routes like this
Route::group([ 'prefix' => 'department/{department}', 'middleware' => [ 'auth.department' ] ], function () {
Route::post('employee/create', 'EmployeeController#store')->name('employees.store');
});
This is my auth.department middleware (AuthDepartment)
class AuthDepartment
{
public function handle($request, Closure $next)
{
$department = Department::find($request->department);
//do something with the department
//I want to set the $department (Department model) in the place of {department} in the route.
return $next($request);
}
}
This is EmployeeController
class EmployeeController extends Controller {
public function store($department)
{
}
}
As you can see in the code, I am using $department parameter to get the department id from the route. But instead of getting the integer as the parameter, I want to bind the model like this.
class EmployeeController extends Controller {
public function store(Department $department)
{
}
}
With my current code, it is not working. I tried to set the route parameter in the middleware as follow to match (bind model) the value in the action.
$request->route()->setParameter('department', $department)
But it is just not working. How can I set/ replace the route parameter with a model in the middleware which can be binded to the parameter in the action of the controller? Is it possible? What could be the better approach?
If I used
$request->route()->setParameter('department', $department)
to set the parameter, I cannot set type in the action of the controller like this.
store(Department $department)
But this is fine
store(Department $department)
But I want this
store(Department $department)
Laravel already has this built in. It is called Route Model Binding.
https://laravel.com/docs/5.7/routing#route-model-binding
Remove the middleware and instead keep your controller as it is. Laravel will automatically use the ID in the request to find the model and give you an instance of it. If the model cannot be found, Laravel will throw a 404 response for you.

Laravel preventing user from accessing other users resource **url

I am passing a specific resource in the url, for ex.
https://www.example.com/{companyID}
And in the controller I can access the resource by
public function index($companyID)
{
// Code Here
}
I need to block users from changing the url and accessing other companyIDs from the system. Currently its open and is a security risk. I checked out Laravel Gate and Policy's but fail to see how this could be implemented for my case.
What I am really looking for is something in the AuthServiceProvider boot method that can check if the user really is the owner of the resource before continuing with the code.
Any help?
As mentioned before, you can do that by creating a Middleware that checks if your resource should be available to the logged in user.
See some details about middleware here
First, create a Middleware via php artisan, like this
php artisan make:middleware AuthResource
Next, add it to your App\Http\Kernel.php
protected $routeMiddleware = [
...
'AuthResource' => \App\Http\Middleware\AuthResource::class,
];
In your routes, you can now do the following:
Route::get('{companyID}', ['uses' => CompanyController#index, 'middleware' => 'AuthResource']);
That way, your AuthResource middleware is used whenenver the route is called.
In your App\Http\Middleware\AuthResource.php you have to change the code from
public function handle($request, Closure $next)
{
return $next($request);
}
to something that checks if the resource is available to the currently logged in user.
I assume that your companies table has a field user_id, which links the Company to a User. If your data structure is different, you need to change the code accordingly.
public function handle($request, Closure $next)
{
if ($request->route('companyID')) {
$company = Company::find($request->route('companyID'));
if ($company && $company->user_id != auth()->user()->id) {
return redirect('/');
}
}
return $next($request);
}
That way we check if the a route parameter with the name companyID exists, and if it does we check if it is available to the currently logged in user. If no companyID parameter is available, the page can be loaded without any restrictions.
That way you can copy/paste the code within the middleware for any parameters so that the middleware does work for multiple resources (not only companies).
This is can be done easily by middleware. But I’ll do this in more understandable way.
I assume that your user has one to one relationship with company.
So first create the relationship,
In your User model,
Public function company() {
return $this->hasOne(‘App\Company’);
}
Company model
Public function user(){
return $this->belongsTo(‘App\User’);
}
So, now make Authenticate by running php artisan make:auth . more details on Authenticate
And now in your controller,
public function index($companyID)
{
$current_user = Auth::user();
$user_company = $current_user->company; // get the current user's company details
If($companyID == $user_company->id){
// do something
}
}

Laravel - middleware on routes in controller

I have a route resource
Route::resource('campaign', 'CampaignController');
I want to restrict some of these routes to the users.
For example the index page lists all the campaigns and they should not see this only their own ones.
I have a custom middleware that simply checks the if the user is an admin
However I cannot apply this to individual methods.
public function index()
{
$this->middleware('checkuser');
}
Just the constructor
public function __construct()
{
$this->middleware('checkuser');
}
How do I get around this and apply to individual route in the controller
Sorry my mistake I should have read the docs you can add exceptions or allowed.
$this->middleware('auth');
$this->middleware('log', ['only' => ['fooAction', 'barAction']]);
$this->middleware('subscribed', ['except' => ['fooAction', 'barAction']]);
}

Laravel using user id in route

So I have a route profile/{user_id}
How do I redirect user to that URL when they click on link?
Here's my controller:
{
function checkid($user_id) {
if (Auth::check())
{
$user_id = Auth::id();
return view('profile', [
'id' => $user_id
]);
}
}
}
Bit confused with the question but Laravel uses ID as default for dependency injection and changing it is easy: just change the routeKey in the model BUT in your instance, you're using the signed in user. So forgot the id!
<?php
namespace App\Http\Controllers;
class RandomController extends Controller {
public function index()
{
return view('profile');//use auth facade in blade.
}
}
In your routes use a middleware to prevent none authenticated users from reaching this method
<?php
Route::group('/loggedin', [
'middleware' => 'auth',
], function() {
Route::get('/profile', 'RandomController#index')->name('profile.index');
});
Now to redirect in your blade file use the route function, don't forget to clear your cache if you've cached your routes!
<h1>Hi! {{Auth::user()->name}}</h1>
View profile
Because I used the name method on the Route I can pass that route name into the route function. Using php artisan route:list will list all your route parameters which is cool because it will also tell you the names and middlewares etc.
if I had a route which required a parameter; the route function accepts an array of params as the second parameter. route('profile.index', ['I_am_a_fake_param' => $user->id,]).
Let me know if you need help with anything else.
You can redirect with the redirect() helper method like this:
return redirect()->url('/profile/' . $user_id);
But I'm not really following your usecase? Why do you want to redirect? Do you always want the user to go to their own profile? Because right now you are using the id from the authenticated user, so the user_id parameter is pretty much useless.

Resources