I have in my web.php the following routes:
Route::get('admin', ['as' => 'admin.login', 'uses' => 'AdminController#login']);
Route::post('admin', ['as' => 'admin.postLogin', 'uses' => 'AdminController#postLogin']);
Route::group(['middleware' => 'isAdmin'], function () {
// problem is when I redirect to the following route
Route::get('admin/transactions', ['as' => 'admin.transactions', 'uses' => 'AdminController#transactions']);
});
and my controller as follow:
public function postLogin(Request $request){
//some logic
return Redirect::to('admin/transactions');
}
and the transaction action:
public function transactions(){
dd('ok');
}
but I still get Resource not found!! why?
Can anybody help me?
Note!!: I have other routes working fine so I don't think it's an .htaccess problem
EDIT!!
here is my middleware:
public function handle($request, Closure $next)
{
if (!Auth::check() || !Auth::user()->admin) {
return Redirect::to('/');
}
return $next($request);
}
Maybe use Route::middleware?
Route::middleware(['isAdmin'])->group(function () {
Route::get('admin/transactions', 'AdminController#transactions');
});
Related
In my Laravel-5.8 application, I have a multi-company application using a single database. Each table have a company_id derived from the company table as shown below:
id | company_name | subdomain
1 | Main |
2 | Company1 | company1
3 | Company2 | company2
Main=> localhost:8888/myapp
Company1=>localhost:8888/company1.myapp
Company2=>localhost:8888/company2.myapp
I created a middleware:
class VerifyDomain
{
public function handle($request, Closure $next)
{
$domain == "myapp"; // your company app name
$path = $request->getPathInfo(); // should return /company1.myapp or /company2.myapp or /myapp
if (strpos($path, ".") !== false) { // if path has dot.
list($subdomain, $main) = explode('.', $path);
if(strcmp($domain, $main) !== 0){
abort(404); // if domain is not myapp then throw 404 page error
}
} else{
if(strcmp($domain, $path) !== 0){
abort(404); // if domain is not myapp then throw 404 page error
}
$subdomain = ""; // considering for main domain value is empty string.
}
$company = Company::where('subdomain', $subdomain)->firstOrFail(); // if not found then will throw 404
$request->session()->put('subdomain', $company); //store it in session
return $next($request);
}
}
Already, I have two (2) route groups in the route/web.php wgich looks like this:
Route::get('/', ['as' => '/', 'uses' => 'IndexController#getLogin']);
Auth::routes();
Route::get('/dashboard', 'HomeController#index')->name('dashboard');
// Config Module
Route::group(['prefix' => 'config', 'as' => 'config.', 'namespace' => 'Config', 'middleware' => ['auth']], function () {
Route::resource('countries', 'ConfigCountriesController');
Route::resource('nationalities', 'ConfigNationalitiesController');
});
// HR Module
Route::group(['prefix' => 'hr', 'as' => 'hr.', 'namespace' => 'Hr', 'middleware' => ['auth']], function () {
Route::resource('designations', 'HrDesignationsController');
Route::resource('departments', 'HrDepartmentsController');
Route::resource('employee_categories', 'HrEmployeeCategoriesController');
});
I have 2 issues:
If subdomain field is null, then the route should be for main domain: Main=> localhost:8888/myapp else localhost:8888/company1.myapp or localhost:8888/company2.myapp
2.How do I accomodate the route groups above into this:
Route::domain('localhost:8888/myapp')->group(function () {
Route::get('/', function ($id) {
//
});
});
Route::domain('localhost:8888/{subdomain}.myapp')->group(function () {
Route::get('/', function ($company_name, $id) {
$company = Company::where('subdomain', $subdomain)->firstOrFail();
// send the value of $company to data to send different view data
});
});
I'm not really sure that i understand you clearly. But, I hope you'll understand me :)
First thing is you're "domain". I suppose it's not real domain, but just uri. And maybe you should use it something like that:
Auth::routes();
$defaultDomain = config('myconfig.default_domain_name', 'myapp');
// I'm not reccomend to you use localhost:8888 here.
Route::domain('localhost:8888')
->group([
'middleware' => ['veryfy_domain'] // Add your VerifyDomain Middleware here
], function () {
// Here you already have a 'subdomain' param in session
// If you need special logic for default domain, you can out it here
Route::group(['prefix' => '/' . $defaultDomain], function () {
Route::get('/', function ($id) {
//
});
});
// Code below will work only with companies.
Route::group(['prefix' => '/{test}.' . $defaultDomain], function () {
Route::get('/', ['as' => '/', 'uses' => 'IndexController#getLogin']);
Route::get('/dashboard', 'HomeController#index')->name('dashboard');
// Config Module
Route::group(['prefix' => 'config', 'as' => 'config.', 'namespace' => 'Config', 'middleware' => ['auth']], function () {
Route::resource('countries', 'ConfigCountriesController');
Route::resource('nationalities', 'ConfigNationalitiesController');
});
// HR Module
Route::group(['prefix' => 'hr', 'as' => 'hr.', 'namespace' => 'Hr', 'middleware' => ['auth']], function () {
Route::resource('designations', 'HrDesignationsController');
Route::resource('departments', 'HrDepartmentsController');
Route::resource('employee_categories', 'HrEmployeeCategoriesController');
});
});
});
And about your middleware. I see it smth like that:
class VerifyDomain
{
public function handle($request, Closure $next)
{
$request->get('domain_name', $this->getBaseDomain());
$company = Company::where('subdomain', $subdomain)->firstOrFail();
$request->session()->put('subdomain', $company);
return $next($request);
}
// Better to store it in config
protected function getBaseDomain()
{
return config('myconfig.default_domain_name', 'myapp');
}
}
If you really want to use different domains, I think you need in your nginx something like this:
server_name *.myapp myapp;
And of course in your hosts file.
Than you can check it like that:
http://company.myapp
http://company1.myapp
http://myapp
Config example:
Create new file your_project_dir/app/config/myconfig.php (name it as you want)
Put this code in the file:
return [
'default_domain_name' => 'myapp'
];
Now you can use in in youre code as i suggest:
config('myconfig.default_domain_name');
I have question about Laravel.
I want display SEO tag automatically from Database but I do not know how to do.
I have route like this
Route::get('/', [
'uses' => 'SeoController#index',
'as' => 'homepage'
]);
Route::get('/about', [
'uses' => 'SeoController#index',
'as' => 'about'
]);
From SeoController I want to display view base on Route url;
public function index()
{
switch ($route) {
case '/':
$title = "Homepage";
return view('welcome', ['title'=> $title]);
break;
case '/about':
$title = "About page";
return view('about', ['title'=> $title]);
break;
default:
break;
}
}
How can I check $route to know which route come?
Thank you so much
I would love to suggest a better way of doing this in Laravel.
In Laravel, you would want to define different controller methods for each pages and return a view like so:
class SeoController extends Controller
{
public function home()
{
return view('home');
}
public function about()
{
return view('about');
}
public function contact()
{
return view('contact');
}
}
Ensure you have the routes registered in web.php as:
Route::get('/', [
'uses' => 'SeoController#home',
'as' => 'homepage'
]);
Route::get('/about', [
'uses' => 'SeoController#about',
'as' => 'about'
]);
Route::get('/contact', [
'uses' => 'SeoController#contact',
'as' => 'contact'
]);
And also ensure you have the corresponding blade file for each of these views in the view folder.
auth()->attempt($credentials, true) is working but its redirecting to /login however! I didn't do anything like that in middleware for example. Can anyone knows what is going on? Thanks
LoginController
public function login(Request $request)
{
$this->validateLogin($request);
$credentials = $request->only('email', 'password');
if (auth()->attempt($credentials, true)) {
// return 'it works';
return redirect()->to('/');
}
return redirect()->back()->withErrors([
'msg' => trans('labels.others.credentials_not_valid')
]);
}
Routes
Route::group(['middleware' => 'auth'], function () {
Route::get('/', ['as' => 'home', 'uses' => 'HomeController#index']);
});
Can someone explain me the following behavior, when i enable my routes (login, homepage etc) like so:
Route::group(['middleware' => 'web'], function () {
....
});
A Ajax login modal is working correctly, however when i try the following (enabling middleware in the controllers) which i prefer working with:
class PagesController extends Controller
{
public function __construct()
{
$this->middleware('web');
}
...
}
class AuthController extends Controller
{
public function __construct()
{
$this->middleware('web');
$this->middleware('guest', ['except' => 'logout']);
}
...
}
A TokenMismatchException is trown in VerifyCsrfToken.php line 67.
To my knowledge there shouldn't be a difference in those two approaches, what am i doing wrong here?
csrf token setup:
Base layout:
<meta name="csrf-token" content="{{ csrf_token() }}">
modal js:
var options = {
emulateJSON: true,
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
};
I'll give You working example, take from there ideas that will help You:
app/Http/routes.php:
// all routes that start with: "/auth" are not filtered by any middleware
Route::group(['prefix' => 'auth'], function() {
Route::get('/', ['as' => 'auth', 'uses' => 'AuthController#index']);
Route::post('/', ['as' => 'auth.attempt', 'uses' => 'AuthController#attempt']);
Route::delete('/', ['uses' => 'AuthController#destroy']);
Route::any('destroy', ['as' => 'auth.destroy', 'uses' => 'AuthController#destroy']);
});
// all routes that start with: "/billing" will be handled by this group (prefix => 'billing')
// all controllers inside this route group are located in 'Billing' namespace
// all routes in this group are pre-checked by middleware 'HasAccessToBilling'
Route::group(['prefix' => 'billing', 'namespace' => 'Billing', 'middleware' => ['App\Http\Middleware\HasAccessToBilling']], function()
{
Route::any('/', ['as' => 'billing', 'uses' => 'DashboardController#index']);
Route::get('profile', ['as' => 'billing.profile', 'uses' => 'ProfileController#index']);
// TARIFFS
Route::group(['prefix' => 'tariffs'], function() {
Route::get('/', ['as' => 'billing.tariffs', 'uses' => 'TariffsController#index']); // showing page with tariffs paginated
Route::get('all', ['as' => 'billing.tariffs.all', 'uses' => 'TariffsController#all']); // listing all tariffs with json (see controller)
Route::get('create', ['as' => 'billing.tariffs.create', 'uses' => 'TariffsController#create']); // create form
Route::post('/', ['as' => 'billing.tariffs.store', 'uses' => 'TariffsController#store']); // creating
Route::get('{id}', ['as' => 'billing.tariffs.edit', 'uses' => 'TariffsController#edit']); // edit form
Route::post('{id}', ['as' => 'billing.tariffs.update', 'uses' => 'TariffsController#update']); // updating
Route::get('{id}/activate', ['as' => 'billing.tariffs.activate', 'uses' => 'TariffsController#activate']); // active = 1
Route::get('{id}/suspend', ['as' => 'billing.tariffs.suspend', 'uses' => 'TariffsController#suspend']); // active = 0
Route::get('{id}/delete', ['as' => 'billing.tariffs.delete', 'uses' => 'TariffsController#delete']); // deleted = 1
});
app/Http/Middleware/HasAccessToBilling.php:
<?php namespace App\Http\Middleware;
use App\Library\Auth;
use Closure;
use Illuminate\Http\Request;
class HasAccessToBilling
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle(Request $request, Closure $next)
{
if (Auth::hasAccessTo('billing', $request)) {
return $next($request);
}
return redirect()->route('auth');
}
}
app/Library/Auth.php:
<?php namespace App\Library;
use \App\Models\User;
use Illuminate\Http\Request;
use Crypt;
class Auth
{
public static function recoverSession(Request $request)
{
$rememberToken = $request->cookie('remember-token', null);
if(is_null($rememberToken)) {
return null;
}
try{
$rememberToken = Crypt::decrypt($rememberToken);
$auth = json_decode($rememberToken, true);
$request->session()->set('auth', $auth);
}
catch(\Exception $ex) {}
return $request->session()->get('auth');
}
public static function hasAccessTo($realm, Request $request)
{
$auth = $request->session()->get('auth', null);
if (is_null($auth)) {
$auth = self::recoverSession($request);
}
return (isset($auth['access_to']))?
in_array($realm, $auth['access_to'])
: false;
}
}
and finally example controller:
see namespace 'Billing' must be same with folder, otherwise You'll do manual class aliasing in composer.
app/Http/Controllers/Billing/TariffsController.php:
<?php namespace App\Http\Controllers\Billing;
use Illuminate\Http\Request;
use Redirect;
use App\Http\Controllers\Controller;
use App\Models\Tariff as Model;
class TariffsController extends Controller
{
/**
* Listing records
* #return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index()
{
$records = Model::paginate();
return view('billing.tariffs.index', compact('records'));
}
/**
* Listing all tariff plans as json
* #return \Illuminate\Http\JsonResponse
*/
public function all()
{
return $this->ok(Model::all());
}
summary:
if You defined middleware in Route::group - so no need for calling middleware inside constructor. Idea of route group is to free You from repeating code when writing routes, when giving accesses using middlewares and etc.
auth controllers must not be guarded by middleware that denies public access if it's not application for intranet. so You can see that in my routes file I've not defined middleware for "/auth" prefix routes.
I don't use csrf tokens (I don't see any reason for it, many years of work I've not ever got the moment where csrf was helpful or saved my life), so I've removed it from Kernel.php.
Here is the code.If sign in it goes to /dashboard route. but after I go to other route user session is not persisting(by dd I found this).thanks in advance if you solve, I spent hours on this.
Route::group(['middleware' => 'web'],function(){
Route::get('/', function () {
return view('welcome');
})->name('home');
Route::get('/dashboard' , [
'uses' => 'UserController#GetDashboard',
'as' => 'dashboard'
]);
Route::post('/signin' , [
'uses' => 'UserController#postSignin',
'as' => 'signin'
]);
});
in my login controller
public function postSignin(Request $request)
{
if(Auth::attempt(['email' => $request['email'],'password' => $request['password']])) {
return redirect()->route('dashboard');
}
return redirect()->back();
}
$request is an object, not an array. Try using $request->get('email').