Web route is
Route::post('/loginext/{username}/{password}', 'LoginControllerExt#checkLogin');
while calling the url
http://localhost/old/loginext/bank/test
It will call the controller and get the response. But that time the url is
http://localhost/old/loginext/bank/test
I want to show the url as
http://localhost/old/
LoginControllerExt Controller
public function checkLogin(Request $request)
{
$LoginID=$request->username;
$Password=$request->password;
$Status='Success';
if($Status == 'Success' ) {
return view('dashboard.index');
}
}
Change route as
Route::post('/loginext', 'LoginControllerExt#checkLogin');
Pass the credentials in request body.Try with postman.
Check the screenshot
In controller
public function checkLogin(Request $request)
{
dd($request->all());
}
Related
I have this policy :
class ProjectPagePolicy
{
use HandlesAuthorization;
public function viewAny(User $user)
{
return true;
}
public function view(User $user, ProjectPage $projectPage)
{
return true;
}
public function create(User $user)
{
return $user->isAdmin() || $user->isDeveloper();
}
public function update(User $user, ProjectPage $projectPage)
{
return $user->isAdmin() || $user->isDeveloper();
}
..........
}
ProjectPageController :
class ProjectPageController extends Controller
{
public function __construct()
{
$this->authorizeResource(ProjectPage::class, 'project-page');
}
public function index(Request $request)
{
return response(
[],
HttpStatusCode::OK
);
}
public function store(ProjectPageRequest $projectPageRequest)
{
$inputs = $projectPageRequest->validated();
$projectPage = ProjectPage::create($inputs);
return response()->json([
'data' => new ProjectPageResource($projectPage)
], HttpStatusCode::Created);
}
public function update(
ProjectPageRequest $projectPageRequest,
ProjectPage $projectPage
) {
$inputs = $projectPageRequest->validated();
$projectPage->fill($inputs)->save();
return response(status: HttpStatusCode::NoContent);
}
In the routes file :
Route::middleware(['auth:sanctum'])->group(function () {
Route::post(
'/refresh-token',
fn () => app(RefreshTokenResponse::class)
);
Route::apiResources([
'project-page' => ProjectPageController::class,
]);
});
When I try to save a project page, I received 201 CREATED so all good in this case.
When I try to update it I have 403 forbidden.
Where the problem is ? Why is working on creation and not on updated ? Have an idea about that ?
TL;DR Remove the second argument ('project-page') from your authorizeResource call.
When using Route::resource(...), Laravel will convert a hyphenated route parameter to be snake-case (this will not have any affect on the URL itself, just how laravel accesses the parameter). This will mean that that when you call authorizeResource with project-page, it won't match. This will in-turn cause the authorize method to fail.
You can view your routes via the CLI with the following:
php artisan route:list
which should show your route param for your project-page routes to be project_page e.g. project-page/{project_page}
I have a problem when I want to pass data to the view via the middleware to count the number of users. when not using middleware, variable from controller get to the view.
my HomeController.php
public function index()
{
$count = User::count();
return view('admin.Dashboard', compact($count);
}
my Middleware
public function handle(Request $request, Closure $next)
{
if ($request->user() && $request->user()->role == 'admin') {
return response()->view('admin.Dashboard');
} else {
return response()->view('member.dashboard');
}
return $next($request);
}
the $count variable if using middleware in route not passed to the view
my web.php
Auth::routes(['verify' => true]);
Route::get('/dashboard', 'HomeController#index')->middleware('verified', 'cekrole')->name('home');
In your middleware you are returning response (a view), so
return $next($request);
will never be executed, so neither will your controller.
User call /dashboard > Your middleware is called > if it's an admin you are returning admin.Dashboard, else member.dashboard.
But you never execute code in your Controller.
As a quick fix you could replace your Middleware by :
public function handle(Request $request, Closure $next)
{
if ($request->user() && $request->user()->role == 'admin') {
$count = User::count();
return view('admin.Dashboard', compact('count'));
}
return response()->view('member.dashboard');
}
or make those test (admin/not admin) in your controller
I have update and store method like this
public function update(ContactRequest $request)
{
if (Auth::user()->can('edit_contact'))
$request->update();
else
return $this->accessDenied();
}
public function store(ContactRequest $request)
{
if (Auth::user()->can('add_contact'))
$request->store();
else
return $this->accessDenied();
}
and authorize in FormRequest class
public function authorize()
{
return \Gate::allows('test', $this->route('contact'));
}
I want to pass permission name to authorize method like this:
public function authorize($permissionName)
{
if (Auth::user()->can($permissionName))
return \Gate::allows('test', $this->route('contact'));
}
and in controller like this
public function update(ContactRequest $request)
{
$request->update('edit_contact');
}
public function store(ContactRequest $request)
{
$request->store('add_contact');
}
You have 3 options:
Change your authorization method to this:
public function authorize()
{
return $this->user()->can(
$this->route()->getActionMethod() === 'store'
? 'add_contact'
: 'edit_contact'
)
&& \Gate::allows('test', $this->route('contact'));
}
Make your authorize method of request return true and check authorization by defining another gate an call it on your controller:
public function authorize()
{
return true;
}
Gate::define('modify_contact', function ($user, $permissionName) {
return $user->can($permissionName)
&& $user->can('test', $request->route('contact'));
});
public function update(ContactRequest $request)
{
Gate::authorize('modify_contact', 'edit_contact');
//...
}
public function store(ContactRequest $request)
{
Gate::authorize('modify_contact', 'add_contact');
//...
}
Define and use policy the same way and pass your arguments to it.
There is no direct way of passing argument to authorize method of form request, but you can do the implementation this way:
public function authorize()
{
$method = Request::method();
if($method == 'post') {
$permission = 'add_contact';
} elseif($method == 'put') {
$permission = 'edit_contact';
}
if (Auth::user()->can($permission))
return \Gate::allows('test', $this->route('contact'));
}
If you are using laravel's default post, put routes then this will help you out.
It is better to make two different Requests for store and update, anyway you need to check some values depended on action.
So you can user default laravel's policy approach for Resource controllers and not use Request::authorize for authorization logic.
Laravel policy controller helpers
I am trying to set up a double authentication page under laravel, for that I add a checkTotp method that verifies that the user has activate double authentication and redirect this user to the page in question.
The problem is that I am not redirected and the code continues to execute.
public function login(Request $request)
{
$this->validateLogin($request);
...
$this->checkTotp($request);
dd('after');
...
}
protected function checkTotp(Request $request)
{
$user = User::where('email', $request->get('email'))->first();
if (!is_null($user->totp_key)) {
$request->session()->put('user_id', $user->id);
return redirect('login/totp');
}
}
What happens is that I enter the checkTotp method but the redirect does not work. My output is the dd('after'). I don't understand why I am not redirected. Can someone help me?
Quentin
The checkTotp function returns a redirect, but you want the login function to return that redirect, such that it is passed to the browser. You might want to move the redirect to the main function and let checkTOTP just return true/false.
public function login(Request $request)
{
$this->validateLogin($request);
...
if ($this->checkTotp($request)) return redirect('login/totp');
dd('after');
...
}
protected function checkTotp(Request $request)
{
$user = User::where('email', $request->get('email'))->first();
if (!is_null($user->totp_key)) {
$request->session()->put('user_id', $user->id);
return true;
}
return false;
}
I have following functions in Controller.
public function UpdateCountry(\App\Http\Requests\CountryRequest $request) {
$this->SaveChanges($request);
}
private function SaveChanges($request) {
if($request['CountryID'] == 0) {
$Country = new \App\Models\CountryModel();
}
else {
$Country = \App\Models\CountryModel
::where('CountryID', $request['CountryID'])->first();
}
$Country->Country = $request['Country'];
$Country->CountryCode = $request['CountryCode'];
$Country->save();
return redirect()->route('AllCountries');
}
public function AllCountries() {
$Countries = \App\Models\CountryModel::all();
return view('Country.List', array('Countries' => $Countries));
}
Issue is in below line: When I call function SaveChanges, I am not able to see List of countries page and when I write the code directly in UpdateCountry function, it redirect route successfully.
return redirect()->route('AllCountries');
Anybody faced this issue before ?
Your route is being handled by the UpdateCountry function. Laravel will take action based on the returned value from this function. However, you're not returning anything from this function.
You call SaveChanges, which returns a Redirect object, but then you don't return anything from your UpdateCountry function. You need that Redirect object from the UpdateCountry function in order for Laravel to actually return the redirect to the client.
Update your UpdateCountry function to this:
// added the return statement, so this function will return the redirect
// to the route handler.
public function UpdateCountry(\App\Http\Requests\CountryRequest $request) {
return $this->SaveChanges($request);
}
Maybe you missed a return in $this->SaveChanges($request). It has to be:
public function UpdateCountry(\App\Http\Requests\CountryRequest $request) {
return $this->SaveChanges($request);
}
I hope it works fine for you.