Route Id Not working - php

I am creating a project called doctor management system. I am now stuck in this that when a user logged in his page my route function get the specific id & then show his information. But when I logged in it did not get id & that's why it put some error but When I manuaaly enter the id it worked perfectly ok. I did not find why this occurs. Please Guys Help Me.
My Route File
Route::group([
'middleware' => 'auth'
], function() {
Route::get('/home/{profile_id}', [
'as' => 'admin',
'uses' => 'AdminController#index'
]);
Route::get('/profile/{profile_id}', array('as' =>'profile' ,'uses' => 'ProfileController#index'));
My profile Controler is
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\User;
class ProfileController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index($profile_id)
{
$profile = User::find($profile_id);
// if(!$profile) {
// return redirect()->route('logout')->with(['fail' => 'Profile Not Found']);
// }
return view('admin.article.index',['profile' => $profile]);
}
The error is

You did not specify what URL is being accessed, so I suppose it is whatever_your_domain_is/profile/{id}.
The error being presented is telling you there is no route for the URL being entered.
I suppose you wanna show the profile for logged-in user, so actually you don't need any {id} in route, you can:
$profile = Auth::user();
return view('admin.article.index', compact('profile'));
But if you do want to show other user's profile, just check out your URL.
Some things I've noticed:
Your 'profile/{profile_id}' route is outside of Route group, that's the way it is supposed to be?
Choose a single pattern to write your code. You've written array using to different notations: array() and []. Read about Coding Stardards (e.g. https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md).

Related

Laravel 9.x Target class does not exist error at login application

trying to make a login application for admin panel to edit rest of the website easily.
I have a controller called AuthController and it performs multiple actions such as login-logout. Instead of two different controllers I decided to use only one.
When I go to /login on my explorer it returns Target class [AuthController] does not exist.
What is the problem? What I am missing?
web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PagesController;
use App\Http\Controllers\ContactUsFormController;
use App\Http\Controllers\AuthController;
Route::get('/', 'App\Http\Controllers\PagesController#index');
Route::get('/about', 'App\Http\Controllers\PagesController#about');
Route::get('/pricing', 'App\Http\Controllers\PagesController#pricing');
Route::get('/completed', 'App\Http\Controllers\PagesController#completed');
Route::get('/contact', [ContactUsFormController::class, 'createForm']);
Route::post('/contact', [ContactUsFormController::class, 'ContactUsForm'])->name('contact.store');
Route::get('login', array(
'uses' => 'AuthController#showLogin'
));
// route to process the form
Route::post('login', array(
'uses' => 'AuthController#doLogin'
));
Route::get('logout', array(
'uses' => 'AuthController#doLogout'
));
AuthController.php
<?php
namespace App\Http\Controllers;
use Redirect;
use Auth;
use Input;
use IlluminateSupportFacadesValidator;
use IlluminateFoundationBusDispatchesJobs;
use IlluminateRoutingController as BaseController;
use IlluminateFoundationValidationValidatesRequests;
use IlluminateFoundationAuthAccessAuthorizesRequests;
use IlluminateFoundationAuthAccessAuthorizesResources;
use IlluminateHtmlHtmlServiceProvider;
class AuthController extends Controller
{
public function showLogin()
{
// Form View
return view('login');
}
public function doLogout()
{
Auth::logout(); // logging out user
return Redirect::to('login'); // redirection to login screen
}
public function doLogin()
{
// Creating Rules for Email and Password
$rules = array(
'email' => 'required|email', // make sure the email is an actual email
'password' => 'required|alphaNum|min:8'
// password has to be greater than 3 characters and can only be alphanumeric and);
// checking all field
$validator = Validator::make(Input::all() , $rules);
// if the validator fails, redirect back to the form
if ($validator->fails()){
return Redirect::to('login')->withErrors($validator) // send back all errors to the login form
->withInput(Input::except('password')); // send back the input (not the password) so that we can repopulate the form
}else{
// create our user data for the authentication
$userdata = array(
'email' => Input::get('email') ,
'password' => Input::get('password')
);
// attempt to do the login
if (Auth::attempt($userdata)){
// validation successful
}else{
// validation not successful, send back to form
return Redirect::to('checklogin');
}
}
}
}
write like this :
Route::get('login', 'App\Http\Controllers\AuthController#showLogin');
insted :
Route::get('login', array(
'uses' => 'AuthController#showLogin'));
For laravel 9 and above, I think you should write like this :
Route::get('login', 'App\Http\Controllers\AuthController#showLogin');
rather than
Route::get('login', [AuthController::class,'showLogin']);
to avoid common error "Target class does not exist". If you type the bottom one it won't work even you add this code, and it also return error
use App\Http\Controllers\AuthController;

Laravel - Log In with only one device

Is there any way that I can allow user to login only from one device?
Thanks in advance
Well, you would need to check at a central place, if there is an already existing session for the user that currently want to log in - and if yes, delete all existing sessions.
The central place would proably be when the login happens or inside an auth middleware.
To delete all existing sessions for the user you can run
DB::table('sessions')->where('user_id', $user->id)->delete();
Log in only from one device, f. ex. Laptop
That is probably not possible as each device would need to send a unique identifier - which it doesn't. As example, your Laptop would need to send a unique identifier to the Laravel system, so that your Laravel application would know, that it is the Laptop the login is coming from.
The login forms normally only takes a username/email and a password, so no unique property to identify your Laptop.
You could probably check for browser user agent or things like this, but that is all fakeable and does not guarantee a 100% proof identification of the device.
You can use deviceInspect middleware and check user agent (it could be fake as #codedge said) and use it after auth middleware
As you can see the user will be authenticated but routes will be protected by device
Create middleware
class DeviceInspect
{
public function handle($request, Closure $next)
{
$user = Auth::user(); //or $request->user()
// TODO get enabled device/s from datebase for $user - by userId
$enabledDevice = "Dalvik/2.2.0 (Linux; U; Android 10.0.1; AM-A89R Build/NMB55D)"; //example
$currentDevice = $request->userAgent(); //or $_SERVER['HTTP_USER_AGENT'];
//it could be fake like codedge said
if ($enabledDevice !== $currentDevice) {
$data = array(
"device" => false,
"message" => "your message to user",
);
return response([$data], 401); // or something else
}
return $next($request);
}
}
add this to App\Http\Kernel
protected $routeMiddleware = [
...
'device' => 'App\Http\Middleware\DeviceInspect',
];
and use it like below
//in controller
class SomeController extends Controller {
public function __construct() {
parent::__construct();
$this->middleware(['auth', "device"]);
}
}
or
//Or in routes
Route::get('/profil', function () {
//
})->middleware(['auth', 'device']);
or
Route::group(['prefix' => '/v1/data', 'namespace' => 'Api\V1', 'as' => 'api.', 'middleware' => ['auth:api', 'device']], function () {
Route::resource('activity', 'Data\DataController', ['only' => ['index', 'show']]);
});

laravel 5 nested routing issue

New to Laravel 5, and building a little Rest test app. So I'm envisioning 2 different endpoints for a single controller.
/myApp/public/index.php/states/{state}/cities //returns cities in a state
and
/myApp/public/index.php/states/{state}/cities/{city} //will do somethin else
its a little unclear to me how to set up the routes for this. I suppose I could have these endpoints use the same controller method, but it seems like better architecture to just route each to its own method.
So far, I've got 2 things that each individually work, but dont work together:
in routes.php
//route to the first endpoint
Route::resource('states.cities', 'StatesController');
//routes to the second endpoint if first is uncommented,otherwise blank page with no errors in log
Route::resource('states.cities', 'StatesController#cities');
And the relevant part of my controller code:
class StatesController extends Controller
{
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index(Request $request, $state)
{
//works
$cities = States::where('state', '=', $state)->lists('name');
echo json_encode($cities);
}
public function cities(Request $request, $state, $city)
{
echo "second request";
echo $state;
echo $city;
}
......
Any one have any ideas on the proper way to handle this going forward? Cheers!
Try this.
Route::get('states/{state}/cities', [
'as' => 'state.cities',
'uses' => 'StatesController#index'
]);
And second.
Route::get('states/cities/{state}/{city}', [
'as' => 'city.of.state',
'uses' => 'StatesController#cities'
]);
Note: There is no need to use resource route in this case. The resource routes creates the whole array of different routes which you really don't need. Resource controllers

Laravel 5 : Restrict access to controllers by User group

I've started learning Laravel 5.1 and so far I'm liking it! But there is one thing I don't get yet..
In my previous project I had 2 specific controllers (eg: "normal", "extended") which , after a successfull login, were called based on the Users user_group from the database.
If "Foo.Bar" enters his valid credentials and has the group normal he is redirected to NormalControler. Since I wasn't using any framework I restricted access to the other group by setting a $_SESSION with the group and checking it. So if another group tried to access that controller he got redirected.
How would this be achievable in Laravel 5? So far I have a controller which is callable without an Authentication and one restricted by this code in routes.php :
// All routes in the group are protected, only authed user are allowed to access them
Route::group(array('before' => 'auth'), function() {
// TO-DO : Seperate Controller access
});
And the login looks like this :
public function performLogin()
{
$logindata = array(
'username' => Input::get('user_name'),
'password' => Input::get('user_pass')
);
if( Auth::attempt( $logindata ) ){
// return \Redirect::to( check group and access this controller based on it);
}
else {
// TO-DO : Redirect back and show error message
dd('Login failed!');
}
}
----- EDIT -----
I've run the artisan command and made this middleware as you suggested :
namespace App\Http\Middleware;
use Closure;
use Request;
class GroupPermissions
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next, $group)
{
// Check User Group Permissions
if( $request->user()->group === $group ){
// Continue the request
return $next($request);
}
// Redirect
return redirect('restricted');
}
}
and edited this line into Kernel.php into $routeMiddleware :
'group.perm' => \App\Http\Middleware\GroupPermissions::class
I think this is done right so far, correct me if I'm wrong! Could I then do something like this to restrict the controllers?
Route::group(array('before' => 'auth'), function() {
Route::group( ['middleware' => 'group.perm', 'group' => 'normal'], function(){
Route::get('/normal/index', 'DummyNormalController#index');
});
Route::group( ['middleware' => 'group.perm', 'group' => 'extended'], function(){
Route::get('/extended/index', 'DummyExtendedController#index');
});
});
Ok, here is what you might do. Once user is logged in, you would check his credentials, get his user_group and decide what controller he should be redirected to.
if( Auth::attempt( $logindata ) ){
$user = Auth::user();
if ($user->inGroup('normal')) {
return redirect()->route('normal_controllers_named_route');
}
return redirect()->route('extended_controllers_named_route');
}
return redirect()->back()->withFlashMessage('don\'t get me wrong');
This will handle right routing after logging in.
The next portion where you need to protect you routes from unwanted user groups may be achieved with middlewares.
do an artisan command php artisan make:middleware ShouldBeInGroup
go to app/http/Kernel.php and add your new middleware to the routeMiddleware array. Key of the item might be anything you like. Let's call in inGroup. So: 'inGroup' => 'App\Http\Middleware\ShouldBeInGroup'
Now, in your controller, in constructor, you are able to call this middleware
$this->middleware('inGroup:extended'); //we also passing the name of the group
at lastly, work on the our middleware. Open newly created ShouldBeInGroup class and edit the handle method.
public function handle($request, Closure $next, $groupName)
{
if (Auth::check() && Auth::user()->inGroup($groupName)) {
return $next($request);
}
return redirect('/');
}
And finally you should work on inGroup method, that should return true of false. I assume that you have user_group field your users table. Then in your User eloquent model add the method
public function inGroup($groupName) {
return $this->user_group == $groupName;
}
Edit
if you want to use this middleware in your routes, you can do the following
Route::group(array('before' => 'auth'), function() {
Route::get('/normal/index', ['middleware' => 'group.perm:normal', 'uses' =>'DummyNormalController#index']);
}
But generally it's better to put all your middlewares into your Controller's constructor
public function __construct(){
$this->middleware('group.perm:normal'); // you can also pass in second argument to limit the methods this middleware is applied to : ['only' => ['store', 'update']];
}
And also on this note, Laravel provides built in auth middleware that you can use
public function __construct(){
$this->middleware('auth');
$this->middleware('group.perm:normal');
}
so then your routes would become much cleaner, just:
Route::get('normal/index', 'DummyNormalController#index');
I think the best way to do that is using middlewares. See the doc here
You can easily create a middleware using the following artisan command:
php artisan make:middleware ExtendedMiddleware
If you can't or don't want to use artisan, you need to create a class in The App/Http/Middleware folder.
In this class you'll need the following method to handle the request. In the method you can check for the user group.
public function handle($request, Closure $next)
{
// check user group
if( user_group_ok )
return $next($request); // Continue the request
return redirect('restricted'); // Redidrect
}
You can then use this middleware in your route.php file:
Route::group(['middleware' => 'auth'], function()
{
// Logged-in user with the extended group
Route::group(['middleware' => 'extended'], function()
{
// Restricted routes here
});
// Normal routes here
});
You can create a Middleware called : PermissionFilter
In PermissionFilter, you check if requesting user is in the group or not.
I can't provide a demo for now, but if you want I can make a demo later.
L5 middleware: http://laravel.com/docs/5.1/middleware

laravel how to create page restriction

Please tell me how to restrict the page using laravel,
i have 3 users.
1. admin, 2. client, 3. partner
i want if admin is logged in then open only- admin.index page
and if client logged in then open only- client.index page
i used in route.php following code-
Route::group(array('before' => 'role'), function(){
Route::resource('admin','AdminController#index');
Route::resource('client','clientController#index');
Route::resource('partner','partnerController#index');
});
using above code this if no any user login then it's coming properly,
and suppose if admin logged in, then page redirect to AdminController but,
if i hard coded (url) hit clientController or partnerController like http://localhost/laravel-login/public/client then client page is coming.
so please tell me how to avoid these
sorry for my english..
thanks
You may use different route filters for each route and create individual filters, for example:
Route::group(array('before' => 'auth'), function() {
Route::resource('admin','AdminController#index');
Route::resource('client','clientController#index');
Route::resource('partner','partnerController#index');
});
In each controller create a __construct method and add filter like:
public function __construct()
{
// In your AdminController
$this->beforeFilter(function() {
if(Auth::user()->role->name != 'admin') return redirect::to('/'); // home
});
}
Same way declare other filters in other controllers:
public function __construct()
{
// In your clientController
$this->beforeFilter(function() {
if(Auth::user()->role->name != 'client') return redirect::to('/'); // home
});
}
And so on. Check more on Laravel website about controller filtering.
The best way to restrict controllers to make new middleware , where you can define rules before the request. example :
I have a admin controller only register users with admin role can access it .
to do so when you define the route include the middleware .
// namespace = indicate where my controller is (sub folder )
// middleware = indicate what restriction i want for my controller you can pass one middleware or array of midlewares
Route::group([ 'namespace' => 'Admin','middleware' => ['auth' , 'IsAdmin'] ], function()
{
Route::resource('admin/posts', 'PostsController');
});
to create the middle ware and register it follow the documentation
look this is my middleware after
<?php
namespace App\Http\Middleware;
use Closure;
class IsAdmin
{
public function handle($request, Closure $next)
{
if($request->user()->is_admin == false ){
return redirect('/');
}
return $next($request);
}
}

Categories