I'm using Laravel 6.x and passport package.
I used api_token in App\User before installing this package.
Now I want to authenticate Users with passport package but I am experiencing this error,
Call to undefined method Illuminate\Auth\TokenGuard::attempt()
This is my gaurd:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
This is my authController:
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
class AuthController extends Controller
{
private $successStatus=200;
public function login(){
if(Auth::attempt(['email' => request('email'), 'password' => request('password')])){
$user = Auth::user();
$success['token'] = $user->createToken('MyApp')-> accessToken;
return response()->json(['success' => $success], $this-> successStatus);
}
else{
return response()->json(['error'=>'Unauthorised'], 401);
}
}
}
You may be having the following configuration:
change your auth.php
passport to token
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
I changed my controller to this and the problem was resolved
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
class AuthController extends Controller
{
public function login(Request $request){
$user = User::whereEmail($request->email)->first();
if($user && Hash::check($request->password, $user->password)){
$success['token'] = $user->createToken('tp_#1')-> accessToken;
return response()->json(['success' => $success],200);
}
else{
return response()->json(['status'=>'invalid username or pass !'], 401);
}
}
}
Related
I just install Laravel passport as follow:
Admin Model:
use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Admin extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
protected $table = 'admins';
}
I just have one guard in auth.php which is API and it's by default.
'defaults' => [
'guard' => 'api',
'passwords' => 'admins',
],
'guards' => [
'api' => [
'driver' => 'passport',
'provider' => 'admins',
'hash' => false,
],
],
LoginController:
use Illuminate\Support\Facades\Auth;
use App\Http\Resources\LoginRequest;
use App\Http\Controllers\Controller;
class LoginController extends Controller
{
public function __invoke(LoginRequest $request)
{
$credentials = $request->only(['email', 'password']);
if (!Auth::attempt($credentials)) {
return $this->jsonResponse(null, trans('auth.failed'), 401);
}
$admin = Auth::user();
$token = $admin->createToken('MyApp')->accessToken;
return (new AdminResourse($admin))->additional([
'meta' => ['token' => $token]
]);
}
}
I got this error in postman:
Method Illuminate\\Auth\\RequestGuard::attempt does not exist.
I clear the cache too, and still same error
I believe the attempt is only available for routes with web middleware.
However you can do:
if (!Hash::check($request->password, $user->password) {
return $this->jsonResponse(null, trans('auth.failed'), 401);
}
The issue with default guard. So it should be web
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
If you keep defaults guard to api then we should manually pass guard
if (!Auth::guard('web')->attempt($credentials)) {
}
I'm using laravel breeze as auth scaffolding package.I want to create Multiple Authentication using laravel guards for two different registration form for two User Types (Admin, User).
The Main Idea of what I want to achieve :
I have two tables in the database one for admins and another for users what I want to achieve is if the admins choose to register an account as admin it will display a register form with specified fields for admin. after that I want to check if the user is logged in as admin or user if is logged in as admin is will redirect him/her to specified dashboard made only for admins.
It works fine for registration, but can't login as a admin here is a simple explanation of what I want to achieve:
app\Models\Admin.php
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class Admin extends Authenticatable
{
use HasFactory, Notifiable;
protected $table = 'admins';
protected $fillable = [
'name',
'email',
'password',
];
config\auth.php
<?php
return [
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
// Admin guards
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
'admin-api' => [
'driver' => 'token',
'provider' => 'admins',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Admin::class,
],
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
'admins' => [
'provider' => 'admins',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
],
'password_timeout' => 10800,
];
app\Http\Middleware\RedirectIfAuthenticated.php
<?php
namespace App\Http\Middleware;
use App\Providers\RouteServiceProvider;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class RedirectIfAuthenticated
{
public function handle(Request $request, Closure $next, ...$guards)
{
$guards = empty($guards) ? [null] : $guards;
// dd($guards);
foreach ($guards as $guard) {
switch ($guard) {
case 'admin':
if (Auth::guard($guard)->check()) {
return redirect()->route('admin.dashboard');
}
break;
default:
if (Auth::guard($guard)->check()) {
return redirect('/dashboard');
}
break;
}
}
return $next($request);
}
}
routes\web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Admin\RegisteredUserController;
use App\Http\Controllers\Admin\AuthenticatedSessionController;
Route::get('/', function () {
return view('welcome');
});
Route::get('/dashboard', function () {
return view('dashboard');
})->middleware(['auth'])->name('dashboard');
require __DIR__ . '/auth.php';
Route::get('admin/dashboard', function () {
return view('backend.dashboard');
})->middleware(['auth:admin'])->name('admin.dashboard');
Route::get('/admin-register', [RegisteredUserController::class, 'create'])
->middleware('guest:admin')
->name('admin.register');
Route::post('/admin-register', [RegisteredUserController::class, 'store'])
->middleware('guest:admin');
Route::get('/admin-login', [AuthenticatedSessionController::class, 'create'])
->middleware('guest:admin')
->name('admin.login');
Route::post('/admin-login', [AuthenticatedSessionController::class, 'store'])
->middleware('guest:admin');
Route::post('/admin-logout', [AuthenticatedSessionController::class, 'destroy'])
->name('admin.logout')
->middleware('auth:admin');
app\Http\Controllers\Admin\AuthenticatedSessionController.php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\LoginRequest;
use App\Providers\RouteServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class AuthenticatedSessionController extends Controller
{
public function create()
{
return view('admin.login');
}
public function store(LoginRequest $request)
{
$request->authenticate();
$request->session()->regenerate();
return redirect('admin/dashboard');
}
public function destroy(Request $request)
{
Auth::logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('/');
}
}
app\Http\Controllers\Admin\RegisteredUserController.php
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Admin;
use App\Providers\RouteServiceProvider;
use Illuminate\Auth\Events\Registered;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
class RegisteredUserController extends Controller
{
public function create()
{
return view('admin.register');
}
public function store(Request $request)
{
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|confirmed|min:8',
]);
Auth::login($user = Admin::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]));
event(new Registered($user));
return redirect('admin/dashboard');
}
}
app\Http\Requests\Admin\LoginRequest.php
<?php
namespace App\Http\Requests\Admin;
use Illuminate\Auth\Events\Lockout;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
class LoginRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'email' => 'required|string|email',
'password' => 'required|string',
];
}
public function authenticate()
{
$this->ensureIsNotRateLimited();
if (! Auth::attempt($this->only('email', 'password'), $this->filled('remember'))) {
RateLimiter::hit($this->throttleKey());
throw ValidationException::withMessages([
'email' => __('auth.failed'),
]);
}
RateLimiter::clear($this->throttleKey());
}
public function ensureIsNotRateLimited()
{
if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) {
return;
}
event(new Lockout($this));
$seconds = RateLimiter::availableIn($this->throttleKey());
throw ValidationException::withMessages([
'email' => trans('auth.throttle', [
'seconds' => $seconds,
'minutes' => ceil($seconds / 60),
]),
]);
}
public function throttleKey()
{
return Str::lower($this->input('email')).'|'.$this->ip();
}
}
After 3 days effort i found a solution myself.
In the function authenticate() in app\Http\Requests\Admin\LoginRequest.php. I have replaced Auth::attempt(...) by Auth::guard('admin')->attempt(...)
public function authenticate()
{
$this->ensureIsNotRateLimited();
if (! Auth::guard('admin')->attempt($this->only('email', 'password'), $this->filled('remember'))) {
RateLimiter::hit($this->throttleKey());
throw ValidationException::withMessages([
'email' => __('auth.failed'),
]);
}
RateLimiter::clear($this->throttleKey());
}
Now it works fine for admin login and register
Ok, so my project is a bit different and not gives a 100% answer but I decided to
leave these here, it may help someone
app/Http/Requests/Auth/LoginRequest.php
public function authenticate()
{
$this->ensureIsNotRateLimited();
if (!Auth::attempt($this->only('email', 'password'), $this->filled('remember')) ||
!auth()->user()->isAdmin() <------------ added
) {
Auth::logout(); <------------ added
RateLimiter::hit($this->throttleKey());
throw ValidationException::withMessages([
'email' => __('auth.failed'),
]);
}
RateLimiter::clear($this->throttleKey());
}
I added the 'isAdmin' function to the user model, it isn't pre built
I'm trying to make a custom login but Auth::attempt returns false.
This my controller:
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;
class MyUserController extends Controller
{
public function authenticate(Request $request)
{
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials)) {
return redirect()->intended('/');
}
}
}
This is auth.php
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'usuarios',
],
'api' => [
'driver' => 'token',
'provider' => 'usuarios',
],
],
'providers' => [
'usuarios' => [
'driver' => 'eloquent',
'model' => Usuario::class,
],
The error I'm getting is
Class '\Usuario' not found {"exception":"[object] (Error(code: 0): Class '\Usuario' not found at /var/www/laravel-boilerplate/vendor/laravel/framework/src/Illuminate/Auth/EloquentUserProvider.php:183)
You're not passing password. Specify the field names
$credentials = $request->only('mail', 'password_laravel');
if (Auth::attempt(['mail'=>$credentials->mail, 'password'=>$credentials->password])) {
$request->session()->regenerate();
return redirect()->intended('/');
} else {
Log::info('Authentication failed.');
}
Notice: Regenerate the session after attempt function. As said here.
In my project, I just need one authentication for admins and not for users and also have users table in my database but I don't want to use it in the authentication and in Admins table I want to use 'AD_AdminEmail' field as email and 'AD_AdminPassword' as authentication password and admins routes separated to management.php file.
These codes below not working and no errors but they redirect me to the login page again and Passwords in database hashed with laravel Hash::make() but Auth::attempt do not recognize it as hashed one and send a select query with plain password not hashed yet.
Here are My web route Codes:
Route::get('/login', [ 'as' => 'login', 'uses' => function() {
return view('LoginAndRegister');
}])->name('login');
Route::post('/ManagerLogin', 'Auth\LoginController#Authenticate');
Here are My LoginController Codes:
<?php
namespace App\Http\Controllers\Auth;
use App\Admin;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Session;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
use AuthenticatesUsers;
protected $redirectTo = RouteServiceProvider::HOME;
public function username()
{
return 'AD_AdminEmail';
}
public function __construct()
{
$this->middleware('guest')->except('logout');
}
protected function credentials(Request $request)
{
return $request->only($this->username(), 'AD_AdminPassword');
}
protected function validateLogin(Request $Request){
$this->validate($Request, [
$this->username() => 'required|email,',
'AD_AdminPassword' => 'required|min:8',
]);
}
public function Show()
{
return view('LoginAndRegister');
}
public function Authenticate(\Illuminate\Http\Request $Request)
{
$AdminEmail = $Request->input('AD_AdminEmail');
$AdminPassword = $Request->input('AD_AdminPassword');
if (Auth::attempt([
'AD_AdminEmail' => $AdminEmail,
'AD_AdminPassword' => $AdminPassword
], false))
echo 200 . "OK";
else
echo 400 . "Problem Found";
}
public function Logout()
{
Session::flush();
Auth::logout();
return back();
}
}
Here are My Admin model Codes:
<?php
namespace App;
use Illuminate\Support\Facades\Auth;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Admin extends Authenticatable
{
protected $fillable = ['AD_AdminEmail', 'AD_AdminPassword'];
protected $hidden = ['AD_AdminId', 'remember_token',];
protected $primaryKey = 'AD_AdminId';
protected $guarded = ['AD_AdminId'];
protected $table = 'Admins';
use Notifiable;
public function getEmailAttribute() {
return $this->AD_AdminEmail;
}
public function setEmailAttribute($Value)
{
$this->attributes['AD_AdminEmail'] = strtolower($Value);
}
public function getAuthPassword()
{
return $this->AD_AdminPassword;
}
public function setPasswordAttribute($Value)
{
$this->attributes['password'] = bcrypt($Value);
}
}
Here are My config>auth.php Codes:
<?php
return [
'defaults' => [
'guard' => 'web',
'passwords' => 'admins',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'admins',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
],
'providers' => [
'admins' => [
'driver' => 'eloquent',
'model' => App\Admin::class,
],
'users' => [
'driver' => 'eloquent',
'model' => App\Admin::class,
],
],
'passwords' => [
'admins' => [
'provider' => 'admins',
'table' => 'password_resets',
'expire' => 60,
],
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
],
'password_timeout' => 10800,
];
I am pretty new to laravel 5.2. Right now I am trying to create a custom login. I created the login html. And on submit, the function shows error
App\User cannot use Illuminate\Foundation\Auth\User - it is not a trait
I couldn't find what is the error. The codes are below
Routes.php
Route::post('/', 'Admin\LoginController#postLogin');
LoginController.php
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Auth;
use Request;
class LoginController extends Controller {
public function index() {
return view('admin.login');
}
public function register() {
return view('admin.register');
}
public function postLogin() {
$email = Request::input('email');
$password = Request::input('password');
if (Auth::attempt(['email' => $email, 'password' => $password])) {
//echo "success";
return redirect('admin/dashboard');
} else {
return redirect('/');
}
}
}
User.php
<?php
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class User extends Model implements AuthenticatableContract, CanResetPasswordContract {
use Authenticatable,
CanResetPassword;
protected $table = 'users';
protected $fillable = ['name', 'email', 'password'];
protected $hidden = ['keyword', 'remember_token'];
}
Auth.php
<?php
return [
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'users' => [
'driver' => 'eloquent',
'model' => 'App\User',
'table' => 'users',
'password' => [
'email' => 'emails.password',
'expire' => 60,
],
],
],
'passwords' => [
'users' => [
'provider' => 'users',
'email' => 'auth.emails.password',
'table' => 'password_resets',
'expire' => 60,
],
],
];
I am following the tutorial from here
Please help me. I am stuck here from last few hours
You should use this namespace:
use Illuminate\Auth\Authenticatable;
It's a trait you should use. Now, you're trying to use a class as a trait:
use Illuminate\Foundation\Auth\User as Authenticatable;
class User {
use Authenticatable ...