I cant make Sentinel work. I don't know what to do anymore, i tried everything, hopefully someone else have some advice.
Problem is in online middleware where check method is false...
EDIT: i found out problem is sessions are not working in middleware, still no solution tho
EDIT2: looks like its permisions, i am on ubuntu, i have run same code with xampp on win10 and everything works fine, still no solution for ubuntu
routes.php
Route::group(['middleware' => ['web']], function () {
Route::get('/', ['as' => 'index' , 'uses' => 'UserController#index']);
Route::post('login', ['as' => 'login' , 'uses' => 'UserController#login']);
Route::post('register', ['as' => 'register' , 'uses' => 'UserController#register']);
Route::get('logout', ['as' => 'logout' , 'uses' => 'UserController#logout']);
Route::group(['prefix' => 'viva' , 'middleware' => ['online']], function () {
Route::get('/', ['as' => 'dashboard' , 'uses' => 'VivaController#dashboard']);
});
});
login method
public function login(){
$data = Input::all();
$credentials = [
'email' => $data["username"],
'password' => $data["password"],
];
$user = Sentinel::authenticate($credentials);
if (!empty($user)){
Sentinel::login($user);
//dd(Sentinel::check()); //---> this gives logged user...
return Redirect::route('dashboard');
}
else{
return Redirect::back()->withErrors(['fail', 'Neuspjela prijava! Molimo pokuĆĄajte ponovo.']);
}
}
online.php Middleware
class online
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next )
{
dd(Sentinel::check()); //---> this is always false
if (Sentinel::check())
{
return Redirect::route('dashboard');
}
else
{
return Redirect::route('index')->withErrors(['fail', 'Nemate prava na pristup ovim stranicama!']);
}
return $next($request);
}
}
For session, I believe you might need these permissions.
Note: assumption that Laravel is installed at /var/www/laravel
cd /var/www/laravel
sudo chgrp -R www-data storage bootstrap/cache
sudo chmod -R ug+rwx storage bootstrap/cache
Related
I have developed an application using Laravvel-5.8.
I have developed the application for just a single company whereby each table have a company_id derived from the company table as shown below:
class Company extends Model
{
protected $table = 'companies';
protected $fillable = [
'id',
'company_name',
'subdomain',
];
}
class User extends Authenticatable
{
protected $fillable = [
'name',
'company_id',
'email',
];
}
and the route/web.php 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');
});
The main route is :
Route::get('/', ['as' => '/', 'uses' => 'IndexController#getLogin']);
which gives localhost:8888/myapp
config/app.php:
'env' => env('APP_ENV', 'production'),
'url' => env('APP_URL', 'localhost:8888/myapp'),
'asset_url' => env('ASSET_URL', null),
I'm asked to add sub-domains where each will see the data based on the company_id in each table
localhost:8888/myapp
localhost:8888/company1.myapp
localhost:8888/company2.myapp
All will use:
Route::get('/', ['as' => '/', 'uses' => 'IndexController#getLogin']);
After successful login will redirect to:
Route::get('/dashboard', 'HomeController#index')->name('dashboard');
Also each will only see it's data based on company_id
companies table:
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
How do I modify:
route/web.php
config/app.php
to achieve this?
Thanks
There are two methods by which It can be done.
By Middleware
As per your question, login page urls can be localhost:8888/myapp, localhost:8888/company1.myapp, or localhost:8888/company2.myapp
Using middleware, we will keep the company name in the session using middleware. You can use it from session.
php artisan make:middleware VerifyDomain
will create a domain
<?php
namespace App\Http\Middleware;
use Closure;
class VerifyDomain
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
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('company_name', $subdomain)->firstOrFail(); // if not found then will throw 404
$request->session()->put('company_name', $company); //store it in session
return $next($request);
}
}
Then add it to route middleware.
In your controller you can redirect to different dashboards as per the company names stored in session.
In route groups
Route::domain('localhost:8888/myapp')->group(function () {
Route::get('/', function ($id) {
//
});
});
Route::domain('localhost:8888/{company_name}.myapp')->group(function () {
Route::get('/', function ($company_name, $id) {
$company = Company::where('company_name', $company_name)->firstOrFail();
// send the value of $company to data to send different view data
});
});
just some weeks ago I started with Laravel and I made some good progress in these weeks with my project.
3 days ago I decided to implement some roles for my users in the system.
I created a middleware via artisan and wrote the code for it.
The problem I have is to assign my middleware to a specific route.
First I added this line to the $routeMiddleware-array in the Kernel.php: 'role' => \App\Http\Middleware\RolesMiddleware::class,.
my routes/web.php-file looks like this on:
// Member area
Route::group(['prefix' => 'member', 'middleware' => ['auth', 'role']], function() {
Route::get('dashboard', ['as' => 'dashboard', 'uses' => function () {
return view('member.dashboard');
}]);
Route::group(['prefix' => 'user'], function() {
Route::get('showUsers',[
'uses' => 'UserController#showUsers',
'as' => 'manageUsers',
'roles' => 'manageUsers'
]);
});
});
First I had only the 'auth' middleware in the first group and I wanted to add my 'role' middleware as additional action directly on my get-route like middleware => 'role:manageUsers'. In this case my middleware was ignored totally and did not get called in any case.
After is put the middleware in the array like in the code above it got called at least.
Now I tried to add a custom action 'roles' with the value 'managerUsers' to my get-route. The middleware still gets called and if output the actions via var_dump(request->route()->getAction()); I see the actions 'uses' and 'as' but not my custom action 'roles'.
I have srsly no clue whats wrong. Does anyone know if it isn't possible to add custom actions or an additional middleware to a specific route?
Best regards.
EDIT 1 (17.07.2017)
My \app\Http\Middleware\RolesMiddleware.php looks like this:
namespace App\Http\Middleware;
use Closure;
class RolesMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #param \string[] ...$roles
* #return mixed
*/
public function handle($request, Closure $next, string ...$roles)
{
var_dump($roles);
die('middleware reachted');
}
}
My \app\Http\Kernel.php looks like this:
...
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'role' => \App\Http\Middleware\RolesMiddleware::class,
];
...
And my \routes\web.php look like this:
...
Route::group(['prefix' => 'member', 'middleware' => ['auth', 'role']], function() {
...
Route::group(['prefix' => 'user'], function() {
Route::get('showUsers',[
'uses' => 'UserController#showUsers',
'as' => 'manageUsers'
]);
});
});
...
If I do assign my middleware as an array together with the "auth" middleware, my one will be called. The point is, that I want to define a role the user has to have with a specific route. (In this case with the Route::get(...))
If I do assign my middleware not together with the "auth" middleware (e.g. in the group with prefix "user"), it will be totally ignored. The same if I do assign my middleware with the get-route directly.
Route::group(['prefix'=>'user', 'middleware'=>'role:manageUsers'], function() {
Route::get('/showUsers',[
'uses' => 'UserController#showUsers',
'as' => 'manageUsers'
]);
});
Your RolesMiddleware.php:
class RolesMiddleware{
public function handle($request, Closure $next, ...$roles){
// sent arguments are stored in $roles array
print_r($roles); // Array ( [0] => manageUsers )
}
}
Have you registered your middleware in your kernel.php?
Best regards...
As usual the problem was in front of the PC.
I copied some more routes for later usage and forgot to change the value for 'as' in the action-array.
Because I'm using the value of the 'as' key for my template to find the correct page I got redirected by another route than expected. Sadly this one pointed to the same controller and action and I didn't noticed the wrong URL in my browsers adress bar.
My role-middleware worked as expected but I just accessed the wrong page.
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.
PROBLEM: AJAX request not working with prefix
Website works great without language prefix. But I need it.. So before (no middleware) and ajax post to domain.com/entitlement worked great.
However, when posting with prefix (domain.com/en/entitlement) and having the pre-fix middleware on throws an error MethodNotAllowedHttpException in RouteCollection.php line 219:
The stackoverflow posts I have seen on prefix routing are focusing on GET related issues. Like Laravel 5 route prefix. I have a POST issue (the GET works fine)
Any ideas?
ROUTES
Route::group(['middleware' => ['web']], function () {
Route::group(
[
'prefix' => LaravelLocalization::setLocale(),
'middleware' => [ 'localeSessionRedirect', 'localizationRedirect' ]
],
function()
{
Route::get('/', array(
'as' => 'home',
'uses' => 'HomeController#getHome'
));
Route::post('/entitlement', array(
'as' => 'entitlement-post',
'uses' => 'HomeController#postEntlitment'
));
}
}
AJAX REQUEST
$.ajax({
type: 'POST',
url: '/entitlement', --> Becomes domain.com/en/entitlement
data: data,
dataType:'json',
beforeSend: function() {
},
...
LocalizationSessionRedirect
<?php namespace Mcamara\LaravelLocalization\Middleware;
use Illuminate\Http\RedirectResponse;
use Closure;
class LocaleSessionRedirect {
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle( $request, Closure $next )
{
$params = explode('/', $request->path());
$locale = session('locale', false);
if ( count($params) > 0 && $locale = app('laravellocalization')->checkLocaleInSupportedLocales($params[ 0 ]) )
{
session([ 'locale' => $params[ 0 ] ]);
return $next($request);
}
if ( $locale && app('laravellocalization')->checkLocaleInSupportedLocales($locale) && !( app('laravellocalization')->getDefaultLocale() === $locale && app('laravellocalization')->hideDefaultLocaleInURL() ) )
{
app('session')->reflash();
$redirection = app('laravellocalization')->getLocalizedURL($locale);
return new RedirectResponse($redirection, 302, [ 'Vary' => 'Accept-Language' ]);
}
return $next($request);
}
}
Thanks to tptcat the answer is to take out middleware of Mcmara's redirect.
UPDATED ROUTE
Route::group(
[
'prefix' => LaravelLocalization::setLocale(),
// 'middleware' => [ 'localeSessionRedirect', 'localizationRedirect' ] --> Not included
],
function()
{
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').