Laravel - Custome Auth Throttlelogins - laravel

I have created a custom authentication and everything is working fine.
Now I am trying to add the Throttlelogins to prevent multiple incorrect login attempts. But The ThrottleLogins doesn't seem to load.
Q: What am I missing here? or am I doing something wrong?
The exception:
Method
App\Http\Controllers\Auth\CustomersLoginController::hasTooManyLoginAttempts
does not exist.
<?php
namespace App\Http\Controllers\Auth;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Validation\ValidationException;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Auth;
class CustomersLoginController extends Controller
{
public function __construct()
{
$this->middleware('guest:customers');
}
public function ShowLoginForm()
{
return view('auth.customer-login');
}
public function login(Request $request)
{
$v = $request->validate([
'email' => 'required|email',
'password' => 'required',
]);
if ($this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
if(Auth::guard('customers')->attempt(['email'=>$request->email,'password'=>$request->password],$request->remember)){
return redirect()->intended(route('customerdashboard'));
};
return $this->sendFailedLoginResponse($request);
}
protected function sendFailedLoginResponse(Request $request)
{
throw ValidationException::withMessages([
$this->username() => [trans('auth.failed')],
]);
}
public function username()
{
return 'email';
}
}
Error Message
Can someone please explain what am I mssing?

The error says you are missing a function: hasTooManyLoginAttempts
In the function login you can see it's trying to call the function but it does not exist in your class. This is where it goes wrong.
update
In the AuthenticateUsers class, which you tried to copy, it's using ThrottlesLogins trait, which you are missing in your controller.
Update your controller like so:
class CustomersLoginController extends Controller
{
use ThrottlesLogins;
Another update
You tried to import the Trait which Laravel uses in their own Login. However this will not work here's why:
When you define a class, it can only have access to other classes within its namespaces. Your controller for instance is defined within the following namespace.
namespace App\Http\Controllers\Auth;
So to use other classes, you need to import them from their own namespaces so you can access them. e.g.:
use Illuminate\Foundation\Auth\ThrottlesLogins;
Now that you have imported the ThrottlesLogins, which is actually a trait, now inside the class you use it to expose all of the methods inside.

Related

Issues with Middleware | Too few arguments to function App\Http\Middleware\HasPermission::handle()

This is the error I'm receiving when I try to load my index page
Too few arguments to function App\Http\Middleware\HasPermission::handle(), 2 passed in /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php on line 180 and exactly 3 expected
I'm using Spatie's Roles and Permissions Package, and have created a custom middleware HasPermission, to check if the user has the permissions to access and utilise the page they are trying to view.
This is the middleware
namespace App\Http\Middleware;
use Closure;
use Spatie\Permission\Models\Permission;
class HasPermission
{
public function handle($request, Closure $next,$permissions)
{
$permissions_array = explode('|', $permissions);
foreach($permissions_array as $permission){
if (!$request->user()->hasPermission($permission)){
return redirect()->back();
}
}
return $next($request);
}
}
The controller
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\User;
use Spatie\Permission\Models\Role;
use DB;
use Hash;
use Illuminate\Support\Arr;
use App\Http\Middleware\HasPermission;
class UserController extends Controller
{
public function __construct() {
$this->middleware('permission:usermgmt.users|usermgmt.users.create|usermgmt.users.edit|users.delete', ['only' => ['index','store']]);
$this->middleware('permission:usermgmt.users.create', ['only' => ['create','store']]);
$this->middleware('permission:usermgmt.users.edit', ['only' => ['edit','update']]);
$this->middleware('permission:users.delete', ['only' => ['destroy']]);
}
And my routes
Route::middleware('HasPermission')->group(function() {
Route::get('/usermgmt/users', [App\Http\Controllers\UserController::class, 'index'])->name('usermgmt.users');
Route::resource('users', UserController::class);
Route::get('add-user', [App\Http\Controllers\UserController::class, 'create'])->name('usermgmt.users.create');
Route::delete('users/{user}',[App\Http\Controllers\UserController::class, 'destroy'])->name('users.destroy');
Route::get('users/{user}/edit', [App\Http\Controllers\UserController::class, 'edit'])->name('usermgmt.users.edit');
});
I have added the HasPermission middleware class to the Kernel.php, but am struggling to understand why I am receiving that error.
Any help would be appreciated, cheers.
I tried initially removing the Route Middleware Group and instead trying to do everything in the controller, and tried something like the below
$this->middleware(HasPermission::class, ['usermgmt.users','usermgmt.users.create','usermgmt.users.edit','users.delete'], ['only' => ['index','store']]);
But this would give me the same error as before.
Did you try this way:
public function handle(Request $request, Closure $next, ...$permissions)
{
foreach($permissions as $permission){
if (!$request->user()->hasPermission($permission)){
return redirect()->back();
}
}
return $next($request);
}
The in your controller, change the syntax:
$this->middleware('permission:usermgmt.users,usermgmt.users.create,usermgmt.users.edit,users.delete', ['only' => ['index','store']]);

basic authorization with livewire and laravel

I have a method in my postpolicy that only current authenticated user can delete his own posts. I try to put this method in my delete method, but it returns that the method does not exist. I have included authroizerequest in the controller, so I'm confused why I get this error.
Method App\Http\Livewire\Posts::authorize does not exist.
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
public $postId = null;
public function deletePost($id)
{
$this->authorize('delete', $this->postId);
$post = Post::find($id);
Storage::delete('public/photos/', $post->image);
$post->delete();
session()->flash('flash.banner', 'Post Deleted Successfully');
}
the policy:
namespace App\Policies;
use App\Models\Post;
use App\Models\User;
use Illuminate\Auth\Access\HandlesAuthorization;
public function delete(User $user, Post $post){
return $user->id === $post->user_id;
}
You are just importing use AuthorizesRequests trait not including this trait inside your class you need to use this trait inside your controller
class ControllerName extends Controller {
use AuthorizesRequests;
}
Using this way you can use AuthorizesRequest traits method inside your class.

How to share one method to all controllers in Laravel?

How to share one method to all controllers with different DI, view and parameters? I need something like this:
public function method(Model $model)
{
$baseData = [
'model' => $model,
'route' => route('$route', [$param => $model]),
];
return view($view);
}
All controllers extend App\Http\Controllers\Controller so you can just place it there
<?php
namespace App\Http\Controllers;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
public function method(Model $model, $route, $param, $view)
{
// Declared but not used
$baseData = [
'model' => $model,
'route' => route($route, [$param => $model]),
];
return view($view);
}
}
And use it with $this->method()
For example in HomeController
<?php
namespace App\Http\Controllers;
use App\User;
class HomeController extends Controller
{
/**
* Show the application dashboard.
*
* #return \Illuminate\Contracts\Support\Renderable
*/
public function index()
{
$user = User::first();
return $this->method($user, 'home', 'user', 'welcome');
}
}
Now accessing domain.tld/home will return the welcome view
If you want to share function to all controller best way will make service in service folder of app.
step to make service:-
1.create service using artisan command
php artisan make:service service_name and define function that to share to all controller in your project.
after making service your have to register this service with provider.make a provider using artisan command.
php artisan make provider:provider_name and you will see 2 function register and boot
register function is used to register your created service and boot for call already register service
register service like this
public function register()
{
$this->app->bind('App\Services\servicename', function( $app ){
return new serviceclassname;
});
}
3.Go config folder ,open app.php where you will get providers array. In this provider you have to define you provider like App\Providers\providerclassname::class,
call this service in controllers like use App\Services\serviceclassname;
public function functionname(serviceclassname serviceobject)
{
serviceobject->functionname();
}

If logged with jwt-auth looks in controller Auth::user() is empty

In my Laravel 5.8/vuejs 2.6 app I use
"tymon/jwt-auth": "^1.0.0",
and my app/Http/Controllers/AuthController.php has method:
public function login(Request $request)
{
$credentials = $request->only('email', 'password');
if ($token = $this->guard('api')->attempt($credentials)) {
return $this->respondWithToken($token);
}
return response()->json(['error' => 'Unauthorized'], 401);
}
and I keep token on client side. It works but I want to add more checks on the server's side, when I save data and to make in control's method :
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Auth;
use DB;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
use App\Settings;
use App\Http\Traits\funcsTrait;
use App\Forum;
use App\ForumCategory;
use App\ForumThread;
use App\ForumPost;
use Illuminate\Routing\Controller as BaseController;
use App\User;
use App\library\CheckValueType;
use App\Http\Requests\ForumThreadRequest;
use JavaScript;
class ForumController extends BaseController
{
use funcsTrait;
public function __construct()
{
$this->middleware('auth');
}
public function add_new_thread(ForumThreadRequest $request)
{
$loggedUser = Auth::user();
if ( empty($loggedUser->id) ) {
return response()->json(['error_code'=> 1, 'message'=> "You must be logged!", 'forumThreadRow'=>null],HTTP_RESPONSE_INTERNAL_SERVER_ERROR);
}
try {
But even if I have logged into the system it looks like that in add_new_thread method $loggedUser is empty.
Have I to make some additive actions in login method of AuthController.php or in which way ?
As I use api guard decision is to use :
$user = Auth::guard('api')->user();
This is a late answer, but maybe could help someone.
I had the same issue and it was fixed by adding $table property to the user model User.php
/**
* Specify table name otherwise Auth::user() will return null
*
* #var string
*/
protected $table = 'users';
see here

Laravel controller / store

I am new to laravel, i am trying to store a tweet to database and i need to insert user id, but this gives me an error
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Tweet;
class TweetController extends Controller
{
public function store(Request $request){
return Tweet::create([ 'tweet' => request('tweet'), 'user_id' => Auth::id()]);
}
}
error i recive:
App\Http\Controllers\Auth' not found in file
/Applications/AMPPS/www/Twitter/Twitter/app/Http/Controllers/TweetController.php
Any idea?
Yes, you are missing the import, that's why it tries to find it in the Controller location, so put
use Illuminate\Support\Facades\Auth;
// or
use Auth; // you must have the Auth alias in the config/app.php array
as an import, or use the helper function auth()->id() instead.
So instead of mass-assigning the user, you can do the following, in your User model add this:
public function tweets()
{
return $this->hasMany(Tweet::class);
}
Then in your controller just do this:
auth()->user()->tweets()->create([ 'tweet' => request('tweet') ]);
You can use auth() helper to get user id:
auth()->user()->id

Resources