I hope my english is good enough to explain my problem. I'm working with laravel 7, and I'm trying to implement my own AuthController, because I can't use migrations and I can't use a table 'users' because I have a db implemented. I've read all the documentation of laravel about authentication and spent days reading a lot of posts with this problem, and I tried everything but still does not work. The problem is with the attempt method. My register method is working fine, but I can't login, actually I tried to put manually the data(that's why credentials are commented) to find the problem but I don't know why is not working
My Regsiter method.
public function storeUser(Request $request)
{
//dd($request);
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:administradores,ADMIN_Correo',
'password' => 'required|string|min:8|confirmed',
'password_confirmation' => 'required',
]);
Administrador::create([
'ADMIN_Nombre' => $request->name,
'ADMIN_Correo' => $request->email,
'ADMIN_Contrasena' => Hash::make($request->password),
]);
//return redirect('home');
}
My Login method.
public function authenticate(Request $request)
{
/*$request->validate([
'ADMIN_Correo' => 'required|string|email',
'ADMIN_Contrasena' => 'required|string',
]);*/
//$credentials = $request->only('ADMIN_Correo', 'ADMIN_Contrasena');
if (Auth::guard('admin')->attempt(['ADMIN_Correo' => 'edwin2#gmail.com
','ADMIN_Contrasena' => '12345678'])) {
return redirect()->intended('home');
}else{
echo 'error';
}
//return redirect('login')->with('error', 'Oppes! You have entered invalid credentials');
}
My config/auth.php file
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
]
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Administrador::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Administrador::class,
],
],
My Model
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class Administrador extends Authenticatable
{
use Notifiable;
protected $table = 'administradores';
protected $primaryKey = 'ADMIN_Id';
public $timestamps = false;
public $incrementing = true;
protected $fillable = ['ADMIN_Nombre','ADMIN_Correo','ADMIN_Contrasena'];
protected $guard = 'admin';
public function getAuthPassword()
{
return $this->ADMIN_Contrasena;
}
}
NOTES The field for password:(ADMIN_Contrasena) is varchar 255
Related
I am trying to authenticate admin in Laravel project. my auth.php as shown below:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Admin::class,
],
AdminController.php
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class AdminController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function adminLogin(){
return view('auth.adminLogin');
}
public function cheackAdminLogin(Request $request){
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:6'
]);
if (Auth::guard('admin')->attempt(['email' => $request->email,
'password' => $request->password])) {
return redirect()->intended('/admin');
}
return back()->withInput($request->only('email')); */
}
}
AdminDashboardController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class AdminDasboardController extends Controller
{
public function adminPanel()
{
return view('adminPanel');
}
}
The problem that I encountered that when I want to check the admin login, the attempt() function when I wrote it, I get an error message in the editor "Undefined Method".
I tried to using auth()->guard('admin')->attempt() instead of Auth::guard('admin')->attempt but the problem is same.
please help
It may be a problem of type hint
use Illuminate\Auth\SessionGuard;
/** #var SessionGuard $adminGuard */
$adminGuard = Auth::guard("admin");
if ($adminGuard->attempt($credentials)) {
...
I am really new to laravel but had experience using PHP, I have this problem with the Auth::attempt() method. It seems that even thought $request->get() gets the value the attempt method doesn't work. I tried checking my Database Table using Schema::hasTable and yes it exists. I am not using the email and password instead I am using a username and password for the login.
LoginController.php
class LoginController extends Controller
{
public function login(){
return view('pages.login');
}
public function dashboard(){
return view('pages.dashboard');
}
public function checklogin(Request $request)
{
$rules = array(
'Username' => 'required|string|min:5',
'Password' => 'required|min:6'
);
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return Redirect::to('/login')
->withErrors($validator) // send back all errors to the login form
->withInput($request->except('Password')); // send back the input (not the password) so that we can repopulate the form
}else{
$userdata = array(
'Password' => $request->get('Password'),
'Username' => $request->get('Username')
);
if (Auth::attempt($userdata,true)) {
// validation successful!
echo 'SUCCESS!';
echo Auth::user()->FirstName;
} else {
// validation not successful, send back to form
echo "ERROR!";
}
}
//Just checking if the value was really been posted
echo $request->get('username').$request->get('password');
}
public function logout()
{
Auth::logout();
return redirect('/');
}
}
Here is the model I created
UsersInfo.php
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Auth\Authenticatable as AuthAuthenticatable;
class UsersInfo extends Model implements Authenticatable
{
use AuthAuthenticatable;
protected $table = 'UsersInfo';
public $primaryKey = 'id';
protected $fillable = [
'Username','Password','MobileNum','AccountNum','FirstName','LastName','Address'
];
public function getAuthPassword(){
return $this->Password;
}
}
auth.php
<?php
return [
'defaults' => [
'guard' => 'web',
'passwords' => 'UsersInfo',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'UsersInfo',
],
'api' => [
'driver' => 'token',
'provider' => 'UsersInfo',
'hash' => false,
],
],
'providers' => [
'Users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'UsersInfo' => [
'driver' => 'eloquent',
'model' => App\UsersInfo::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
'passwords' => [
'UsersInfo' => [
'provider' => 'UsersInfo',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
],
'password_timeout' => 10800,
];
When passing the credentials to attempt the field holding the password must be named password (in this exact case). This is how the user provider knows what field in the credentials is supposed to be the password. The password is something that is checked after a record is found and is not part of the query.
$userdata = [
'password' => $request->input('Password'),
'Username' => $request->input('Username'),
];
Passwords are hashed, you can not directly compare this to the database value, the password field is not part of the query to find the user. Every thing else in the credentials array is a where condition.
I am trying to create a new type of login that works alongside users table called business_users.
I have added the associated, tables, models and config into my auth.php files.
Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\User as Authenticatable;
class BusinessUser extends Authenticatable
{
protected $fillable = ['first_name', 'last_name', 'email', 'password', 'username'];
protected $hidden = [
'password', 'remember_token',
];
protected $guard = 'business_user';
public function business()
{
return $this->belongsTo('App\Business');
}
public function username()
{
return 'username';
}
public function getAuthPassword()
{
return $this->password;
}
}
auth.php
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'business_user' => [
'driver' => 'session',
'provider' => 'business_users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
],
...
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'business_users' => [
'driver' => 'eloquent',
'model' => App\BusinessUser::class,
],
],
Route (which fakes a login for testing)
Route::get('/business/fake-login', function () {
$user = \App\BusinessUser::first();
if (Auth::guard('business_user')->attempt(['username' => $user->username, 'password' => $user->password])) {
return redirect()->intended('/business/dashboard');
}
});
I am trying to use the business.username and business.password to login but the Auth:guard condition above returns false.
Can anyone explain what I'm doing wrong?
(fyi I am using Laravel 7.x)
You are retriving $user from the database, the password is encrypted.
Auth::attempt() will encrypt the password for you, so in the check password part, your password is actually being encrypted twice.
Instead, you may use Auth:attempt() like this:
$res = Auth::guard('business_guard')->attempt([
'username' => "test",
'password' => "test",
]);
dd( $res );
To understand further, you can go to EloquentUserProvider.php
public function validateCredentials(UserContract $user, array $credentials)
{
$plain = $credentials['password'];
return $this->hasher->check($plain, $user->getAuthPassword());
}
Use you original code, and dd() the $plain to see what's going on.
I have a two table login: examinee and company. company is my default auth,
every time i try to attempt auth in examinee it keeps on using the default table which is the company.
I've seen several problems that are similar to mine but it doesn't seem to work for me or I might have overlooked something that maybe some of you might be able to see.
What am I doing wrong?
Auth.php:
'defaults' => [
'guard' => 'web',
'passwords' => 'companies',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'companies',
],
'api' => [
'driver' => 'token',
'provider' => 'companies',
],
'examinees' => [
'driver' => 'session',
'provider' => 'examinees',
],
],
'providers' => [
'companies' => [
'driver' => 'eloquent',
'model' => App\Company::class,
],
'examinees' => [
'driver' => 'eloquent',
'model' => App\Examinee::class,
],
],
'passwords' => [
'companies' => [
'provider' => 'companies',
'table' => 'password_resets',
'expire' => 60,
],
'examinees' => [
'provider' => 'examinees',
'table' => 'password_resets',
'expire' => 60,
],
],
LoginController:
public function showLoginForm()
{
return view('examinee.auth.login');
}
protected function guard()
{
return Auth::guard('examinees');
}
public function login(Request $request) {
$user = Examinee::where('email', $request->get('email'))->first();
if (Auth::attempt(['id' => $user->id, 'password' => $request->get('password')])) {
// prints data from Company table instead of Examinee...
echo "AUTH USER:<pre>";
print_r(Auth::user());
echo "</pre>";
// return redirect('/home');
}
}
Model:
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Examinee extends Authenticatable
{
use Notifiable;
protected $table = 'examinees';
protected $fillable = ['email', 'password'];
protected $hidden = ['password', 'remember_token'];
public $timestamps = false;
}
How ive done this in the past is to add the guard to your auth
Change
Auth::attempt(['id' => $user->id, 'password' => $request->get('password')
to
Auth::guard('examinees')->attempt(['id' => $user->id, 'password' => $request->get('password')
I use Lavarel 5.2 framework with jwt for authorization
jwt takes user info form token just with one model,
now how can i parse user token with jwt on multiple model?
For sample when i use customer token in a api jwt parse that token from customer model , default guard should be customer
auth.php :
'defaults' => [
'guard' => 'operator',
'passwords' => 'operators',
],
'guards' => [
'operator' => [
'driver' => 'session',
'provider' => 'operators',
],
'customer' => [
'driver' => 'session',
'provider' => 'customers',
],
'biker' => [
'driver' => 'session',
'provider' => 'bikers',
]
],
'providers' => [
'operators' => [
'driver' => 'eloquent',
'model' => App\Http\Services\Auth\Model\User::class,
],
'customers' => [
'driver' => 'eloquent',
'model' => App\Http\Aggregate\Customer\Model\Customer::class,
],
'bikers' => [
'driver' => 'eloquent',
'model' => App\Http\Aggregate\Biker\Model\Biker::class,
]
],
You can create a separate middleware like AuthModel. In that you can set the config to take which providers like the below,
Config::set('auth.providers.users.model',\App\Models\Customer::class);
If you want to use multiple models, then need to use if conditions to check which url can access which models. It can be like,
if(url == '/customer/api/') {
Config::set('auth.providers.users.model',\App\Models\Customer::class);
} else if(url == '/biker/api/') {
Config::set('auth.providers.users.model',\App\Models\Biker::class);
}
In the above example, I have used url just for example, so get it from the request.
You can change the __construct function in each of your controllers as follows. So that jwt know which model to authenticate.
BikerController
function __construct()
{
Config::set('jwt.user', Biker::class);
Config::set('auth.providers', ['users' => [
'driver' => 'eloquent',
'model' => Biker::class,
]]);
}
CustomerController
function __construct()
{
Config::set('jwt.user', Customer::class);
Config::set('auth.providers', ['users' => [
'driver' => 'eloquent',
'model' => Customer::class,
]]);
}
This is my solution. Tested on Laravel 6
User Model
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\SoftDeletes;
use Tymon\JWTAuth\Contracts\JWTSubject;
class User extends Authenticatable implements JWTSubject
{
use SoftDeletes;
use Notifiable;
public $incrementing = false;
protected $keyType = 'string';
protected $fillable =
[
];
protected $hidden =
[
'password',
'created_at',
'updated_at',
'deleted_at'
];
public function getJWTIdentifier()
{
return $this->getKey();
}
public function getJWTCustomClaims()
{
}
}
Teacher Model
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\SoftDeletes;
use Tymon\JWTAuth\Contracts\JWTSubject;
class Teacher extends Authenticatable implements JWTSubject
{
use SoftDeletes;
use Notifiable;
public $incrementing = false;
protected $keyType = 'string';
protected $fillable =
[
];
protected $hidden =
[
'password',
'oldpassword',
'created_at',
'updated_at',
'deleted_at'
];
public function getJWTIdentifier()
{
return $this->getKey();
}
public function getJWTCustomClaims()
{
}
}
config/auth.php
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'users'
],
'teacher-api' => [
'driver' => 'jwt',
'provider' => 'teachers'
],
],
AuthController function :
if (
$request->getRequestUri() ===
'OTHER_AUTH_ROUTE'
) {
$credentials = $request->only('username', 'password']);
$token = Auth::shouldUse('teacher-api');
$token = Auth::attempt($credentials);
if (!$token) {
return response()->json(['error' => 'Unauthorized'], 401);
}
return $this->respondWithToken($token);
}
$credentials = $request->only([USERNAME, 'password']);
$token = Auth::attempt($credentials);
if (!$token) {
return response()->json(['error' => 'Unauthorized'], 401);
}
return $this->respondWithToken($token);
Hope this can help you all at future
Laravel 8 compatible
For others still looking for a clean solution:
I would suggest manually configure the providers and guards in config/auth.php and not programmatically change any providers.
The next thing to make sure the right JWTSubject auth model is used, is to create different Middleware (don't forget to specify it in Kernel.php under $routeMiddleware) for a group of routes that has to be only accessible by a specific guard/auth model. Then a middleware handle function could look like this for a Manager model:
public function handle(Request $request, Closure $next) {
if (!($request->user('managers'))) abort(401);
Auth::shouldUse('managers');
return $next($request);
}
Then create another middleware for, let's say an Employee model and change the 'managers' guard value to 'employees' which you configured in config/auth.php.
In your routes/api.php you can specify a route group using (e.g.):
Route::group(['middleware' => 'management'], function() { });
In order to make this all work correctly, specify the guard when the auth()->attempt() function is called, e.g. auth('managers')->attempt($credentials)).