I'm new in laravel.I am using entrust Roles and permission which is working fine, but now I need to add every role like admin has his own controller and view. Superadmin should have his own controller and view.
Can anyone please help me?
How to access permission based controller and view using entrust.
This is how I tried:
Route::group(['middleware' => ['auth']], function() {
if(Entrust::hasRole('superadmin')) {
return View::make('superadmin');
}
else if(Entrust::hasRole('Admin')) {
return View::make('admin');
}
else {
Auth::logout();
return Redirect::to('/login')
->with('flash_notice', 'You don\'t have access!');
}
Route::get('/home', 'HomeController#index');
Route::resource('users','UserController');
Route::get('roles',['as'=>'roles.index','uses'=>'RoleController#index','middleware' => ['permission:role-list|role-create|role-edit|role-delete']]);
Route::get('roles/create',['as'=>'roles.create','uses'=>'RoleController#create','middleware' => ['permission:role-create']]);
Route::post('roles/create',['as'=>'roles.store','uses'=>'RoleController#store','middleware' => ['permission:role-create']]);
Route::get('roles/{id}',['as'=>'roles.show','uses'=>'RoleController#show']);
Route::get('roles/{id}/edit',['as'=>'roles.edit','uses'=>'RoleController#edit','middleware' => ['permission:role-edit']]);
Route::patch('roles/{id}',['as'=>'roles.update','uses'=>'RoleController#update','middleware' => ['permission:role-edit']]);
Route::delete('roles/{id}',['as'=>'roles.destroy','uses'=>'RoleController#destroy','middleware' => ['permission:role-delete']]);
you should use Entrust middlewares in your routes.php. add "superadmin" routes in "superadmin" middleware, "admin" routes in "admin" middleware, etc. and put the "else" case after all these.
Route::group(['middleware' => ['role:superadmin']], function() {
Route::get('/someroute', function(){
return View::make('superadmin');
});
});
Route::group(['middleware' => ['role:admin']], function() {
Route::get('/someroute', function(){
return View::make('admin');
});
});
Route::get('/someroute', function(){
Auth::logout();
return Redirect::to('/login')
->with('flash_notice', 'You don\'t have access!');
});
Related
I know this is a basic laravel question but don't know how do it. How can I add one route to 2 different middleware (auth) without having to duplicate it?
// =admin
Route::group(['middleware' => ['auth']], function() {
Route::get('/dashboard', 'App\Http\Controllers\DashboardController#index')->name('dashboard');
Route::get('make-a-sale', [PurchasesController::class, 'index'])->name('make-a-sale.index');
});
// =cashier
Route::group(['middleware' => ['auth', 'role:cashier']], function() {
Route::get('/dashboard/cashier/profile', 'App\Http\Controllers\DashboardController#showCashierProfile')->name('dashboard.cashier.profile');
Route::get('make-a-sale', [PurchasesController::class, 'index'])->name('make-a-sale.index');
});
I have this route and I don't want to repeat calling this per auth middleware: Route::get('make-a-sale', [PurchasesController::class, 'index'])->name('make-a-sale.index');
You can't have two routes with the same url.
Route::get('make-a-sale', [PurchasesController::class, 'index'])->name('make-a-sale.index');
This route is inside both groups and since the url they will produce will be the same, only the second will remain.
Route::group(['middleware' => ['auth']], function() {
Route::get('/dashboard', 'App\Http\Controllers\DashboardController#index')->name('dashboard');
//Route::get('make-a-sale', [PurchasesController::class, 'index'])->name('make-a-sale.index');
// this route will be ignored because the other one has the same url
});
Route::group(['middleware' => ['auth', 'role:cashier']], function() {
Route::get('/dashboard/cashier/profile', 'App\Http\Controllers\DashboardController#showCashierProfile')->name('dashboard.cashier.profile');
Route::get('make-a-sale', [PurchasesController::class, 'index'])->name('make-a-sale.index');
});
If you want Laravel to handle these two routes differently, you have to add a prefix:
Route::group(['prefix' => 'admin', 'as' => 'admin.', 'middleware' => ['auth']], function() {
Route::get('/dashboard', 'App\Http\Controllers\DashboardController#index')->name('dashboard');
//Route::get('make-a-sale', [PurchasesController::class, 'index'])->name('make-a-sale.index');
// this route will be ignored because the other one has the same url
});
Route::group(['prefix' => 'cashier', 'as' => 'cashier.', 'middleware' => ['auth', 'role:cashier']], function() {
Route::get('/dashboard/cashier/profile', 'App\Http\Controllers\DashboardController#showCashierProfile')->name('dashboard.cashier.profile');
Route::get('make-a-sale', [PurchasesController::class, 'index'])->name('make-a-sale.index');
});
This way, when the url will be prefixed with admin, the first route will be called (without the role:cashier middleware).
Notice that I added a route name prefix ('as' => 'admin.' / 'as' => 'cashier.') so you can call each one by name, using:
route('admin.make-a-sale.index'); // admin/make-a-sale
//or
route('cashier.make-a-sale.index'); // cashier/make-a-sale
Just to add, if someone wants to fix the Laravel blade error below whenever you clear your browser cache and was automatically logout:
*Attempt to read property "name" ...*
You need to add all your routes inside the:
Route::group(['middleware' => ['auth']], function () {
// routes here
});
This will redirect you to login once that happens.
These are my routes for which I am facing problem
Route to get the list of registered places in a particular city
Ex: http://localhost:8000/London, http://localhost:8000/London/Restaurants
Route::group(['namespace' => 'Page'], function() {
Route::group(['prefix' => '{city}', 'where' => ['city' => '[\w\d]+']], function() {
Route::get('/', 'CityPageController#showCityPage')->name('cityPage');
});
});
Route to get a particular user profile and its details such as reviews, photos etc.
Ex: http://localhost:8000/John, http://localhost:8000/John/reviews, http://localhost:8000/John/photos
Route::group(['namespace' => 'User'], function() {
Route::group(['middleware' => 'verified'], function() {
Route::group(['prefix' => '{username}', 'where' => ['username' => '[\w\d]+']], function() {
Route::get('/', 'ProfileController#showProfilePage')->name('profilePage');
Route::get('/reviews', 'ReviewController#showReviewPage')->name('reviewPage');
Route::get('/photos', 'ImageController#showPhotoPage')->name('photoPage');
});
});
});
The problem is that both of these routes are not working simultaneously.
The route the resides above the other takes precedence over the other route.
how to solve this problem of routing.
Edit
I know there is a way to achieve this functionality but I don't know how. Any help is appreciated.
Note: If you haven't, firstly I recommend to create a unique slug field on database first that will appear on url
Your route file
Route::get('{slug1}', 'PageController#singleSlug'); # slug 1 has to be unique i.e. username and cityname
Route::get('{slug1}/{slug2}', 'PageController#doubleSlug'); # combination of slug1 and slug2 has to be unique
The controller functions
public function singleSlug($slug1)
{
$user = User::where('name', $slug1)->first();
if ($user) {
return view('user')->compact('user');
}
$city = City::where('name', $slug1)->first();
if ($city) {
return view('city')->compact('city');
}
abort(404); # neither user nor city
}
public function doubleSlug($slug1, $slug2)
{
// check the slug2 as this value is always defined by the system
switch ($slug2) {
case 'Restaurants':
$city = City::with('restaurants')->where('name', $slug1)->first();
if ($city) {
$viewName = 'city_restos_listing';
$viewData = $city;
}
break;
case 'reviews':
$user = User::with('reviews')->where('name', $slug1)->first();
if ($user) {
$viewName = 'user_reviews_listing';
$viewData = $user;
}
break;
case 'photos':
$user = User::with('photos')->where('name', $slug1)->first();
if ($user) {
$viewName = 'user_photos_listing';
$viewData = $user;
}
break;
default:
abort(404); # the slug 2 is incorrect
break;
}
if(isset($viewName)) {
return view($viewName)->compact('viewData');
} else {
abort(404); # user or city not found
}
}
from Laravels point of view, both urls are the same:
{property}/
having different property names city and username doesn't make a differance because laravel will not understand that london is a city and say Prateek is a username.
A better approach I would suggest is to add an identefier of the model name before the prefix: EX. Route::group(['prefix' => 'users/{username}' ... instead of your approach and city before the city route.
have a look at this: https://laravel.com/docs/6.x/controllers#resource-controllers
add a prefix to distinguish these two kinds of route
Route::group(['prefix' => 'users/{username}'
and Route::group(['prefix' => 'cities/{city}'
An easy way to solve this issue :
Route::group(['namespace' => 'Page'], function() {
Route::group(['prefix' => 'city/{city}', 'where' => ['city' => '[\w\d]+']], function() {
Route::get('/', 'CityPageController#showCityPage')->name('cityPage');
});
});
Route::group(['namespace' => 'User'], function() {
Route::group(['middleware' => 'verified'], function() {
Route::group(['prefix' => 'profile/{username}', 'where' => ['username' => '[\w\d]+']], function() {
Route::get('/', 'ProfileController#showProfilePage')->name('profilePage');
Route::get('/reviews', 'ReviewController#showReviewPage')->name('reviewPage');
Route::get('/photos', 'ImageController#showPhotoPage')->name('photoPage');
});
});
});
I get user data via this link:
https://www.example.com/api/v1/user?api_token=e0220d90-e6e4-11a2-bddd-c6a491dff8e7mb
and in api.php
Route::group(['prefix' => 'v1', 'namespace' => 'API\v1','middleware' => 'auth:api'], function () {
Route::get('/user' , 'AuthController#user');
});
when api_token is true, it return me user data.
but when api_token is false, it return me an error:
"Session store not set on request."
I try add this code in end of api.php to handle wrong api_token
Route::fallback(function () {
return response(['status' => 403]);
});
But again,I get same error
what is my problem?
I have created some apis thats work fine. Now when someone hit that protected apis url that have get request on web browser then it redirect to login of auth system. How can I override this functionality?
Full Details
I am working in laravel application in which I have implemented passport and auth system. This project has not any web interface till date.
This is my api.php
Route::group(['middleware' => ['auth:api'],'namespace' => 'Api', 'prefix' => '/v1'], function () {
Route::get('/user/profile', 'UserController#profile');
Route::get('/logout', 'Auth\LoginController#logout');
});
Route::group(['middleware' => ['api'], 'namespace' => 'Api', 'prefix' => '/v1'], function () {
Route::post('/auth/register', 'Auth\RegisterController#create');
Route::post('/auth/login', 'Auth\LoginController#login');
Route::post('/auth/password/email', 'Auth\ForgotPasswordController#getResetToken');
Route::post('/auth/password/reset', 'Auth\ResetPasswordController#reset');
});
and this is my web.php
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/home', 'HomeController#index')->name('home');
When I hit
{{site_url}}/api/v1/user/profile
without passing or with invalid access token in postman then it returns the following error(this is OK).
{"status":"fail","success":0,"error":401,"message":"Invalid Token!"}
But when I hit this url in web browser then it redirect me to login page.
I solved this problem by adding these functions to /app/Exceptions/Handler.php:
public function unauthenticated($request, AuthenticationException $exception){
if($request->expectsJson()){
return response()->json('Please login',401);
}
return redirect()->guest('admin/login');
}
public function unauthorized($request, AuthorizationException $exception){
if($request->expectsJson()){
return response()->json("You don't have permission to do this",401);
}
return redirect()->guest('login');
}
I have setup multi-domain routing in my laravel 5.2 app. What I want to achieve is if a user hits, membership.app, he should be served different homepage as compared to user who hits, erp.app domain.
Route::pattern('erp', 'erp.app|erp.domain.com');
Route::pattern('membership', 'membership.app|membership.domain.com');
Route::group(['middleware' => ['web', 'auth'], 'domain' => '{erp}'], function() {
Route::get('/', 'HomeController#getIndex');
Route::controller('members', 'MembersController');
Route::controller('users', 'UsersController');
Route::controller('settings', 'SettingsController');
});
Route::group(['middleware' => 'web', 'domain' => '{erp}'], function () {
Route::controller('auth', 'Auth\AuthController');
});
Route::group(['middleware' => 'web', 'domain' => '{membership}'], function () {
Route::controller('/', 'BecomeMemberController');
});
Route::group(['middleware' => 'web'], function () {
Route::controller('ajax', 'AjaxController');
});
I tried this setup, but it breaks the code with first param in each controller method being the url instead of intended value.
Suppose I have a method hello in members controller.
public function hello($param1, $param2)
{
....
}
If I access erp.app/members/hello/1/2 url and try to print out $param1 of controller method, it returns erp.app instead of intended 1 in this case.
Please help.
I don't know why aren't you seperating the routes to different controllers as you say the output will be quite different...
A quick example of to use that:
Route::group(['domain' => '{type}.myapp.com'], function () {
Route::get('members/hello/{id1}/{id2}', function ($type, $id1, $id2) {
// when you enter --> members.myapp.com/hello/12/45
var_dump($type); //memebers
var_dump($id1); //12
var_dump($id2); //45
});
});