Laravel authenticate always fails without default user - php

I'm doing something wrong?
My If (Auth::attempt($validated)) {} always fails when I change default user. But work with default user. Maybe i forgot any config in my new user 'personal'?
config/auth.php
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\Personal::class,
],
App/Models/Personal.php
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Personal extends Authenticatable
{
use HasFactory;
protected $table = 'personals';
protected $fillable = [
'name',
'email',
'password',
];
protected $hidden = [
'password',
'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
}
App\Http\Requests\AuthRequest.php
use Illuminate\Foundation\Http\FormRequest;
class AuthRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'email' => 'required|email',
'password' => 'required'
];
}
}
App\Http\Controller\AuthController.php
public function login(AuthRequest $request)
{
$validated = $request->validated();
if ($validated) {
\Log::info($validated); //<- so far it works
if (Auth::attempt($validated)) { //<- this if always fails with personal model, but it work with default user model
\Log::info('test');
$personal = Auth::user();
return redirect()->route('dashboard');
}
return redirect()->back()->withInput()->withErrors(['algo deu errado']);
}
return redirect()->back()->withInput()->withErrors(['Preencha todos os campos']);
}
$validated = [ 'email' => 'teste#outlook.com', 'password' => 'teste123', ];

Related

Spatie assignRole not working (Call to undefined method Illuminate\Database\Eloquent\Relations\BelongsTo::sync())

Spatie user role permissions not working
Here is my RoleController.php
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
public function saveUserRoles(Request $request)
{
$validator = Validator::make($request->all(), [
'role_name' => 'required|string|unique:roles,name',
]);
if ($validator->fails()) {
alert()->error(trans($validator->messages()->all()[0]));
return back();
}
$role = new Role;
$role->name = $request->role_name;
$role->guard_name = config('auth.defaults.guard');
$role->save();
alert()->success(trans('New Role Created Successfully!'));
return redirect()->route('admin.add.user.roles');
}
User Model
User.php
use Spatie\Permission\Models\Role;
use Spatie\Permission\Traits\HasRoles;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Model;
class User extends Authenticatable
{
use Notifiable;
use SoftDeletes, HasApiTokens;
use HasRoles;
protected $fillable = [
'user_id', 'profile_image', 'name', 'email', 'address','phone','location','role_id','auth_type', 'password','status'
];
protected $hidden = [
'password', 'remember_token',
];
public function role()
{
return $this->belongsToMany(Role::class, 'role_id');
}
}
UserController
UserController.php
use Spatie\Permission\Models\Role;
use App\Http\Requests\UserCreateRequest;
public function saveUser(UserCreateRequest $request)
{
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
'role_id' => $request->role_id,
'status' =>0,
]);
$role = Role::find($request->role_id);
$user->assignRole([$role->name]);
}
When i try to create a new user it shows an error
BadMethodCallException
Call to undefined method Illuminate\Database\Eloquent\Relations\BelongsTo::sync()
Here only need role option without any permissions
Here is your solution, as given in the documentation.

404 error when submitting user form in the registrationController laravel

I get a 404 error when I try to insert user's details into multiple tables during registration
my user model:
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Traits\HasRoles;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Hash;
class User extends Authenticatable
{
use Notifiable;
use HasRoles;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'username','accno', 'email', 'password', 'role', 'status', 'activation_code'
];
protected $guarded = [];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
// a mutator for the email attribute of our model with email validation check and check to avoid duplicate email entries.
protected $table = 'users';
public $timestamps = false;
public $incrementing = false;
public function setEmailAttribute($email)
{
// Ensure valid email
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new \Exception("Invalid email address.");
}
// Ensure email does not exist
elseif (static::whereEmail($email)->count() > 0) {
throw new \Exception("Email already exists.");
}
$this->attributes['email'] = $email;
}
public function setPasswordAttribute($password)
{
$this->attributes['password'] = Hash::make($password);
}
public function profiles()
{
return $this->hasOne(profiles::class);
}
public function accounts()
{
return $this->hasOne(accounts::class);
}
public function transactions()
{
return $this->hasMany(transactions::class);
}
}
I try refactoring by separating my validation code from my logic using RegisterUserTrait
<?php
namespace App\Traits;
use App\User;
use App\Profile;
use App\Account;
use Keygen;
trait RegisterUser
{
public function registerUser($fields)
{
$user = User::create([
'username' => $fields->username,
'accno' => $this->generateAccountNumber(),
'email' => $fields->email,
'password' => $fields->password = bcrypt(request('password')),
'roles' => $fields->roles,
'activation_code' => $this->generateToken()
]);
Profile::create([
'accno' => $user->accno,
'username' => $user->username,
'acc_type' => $fields->acc_type,
'firstname' => $fields->firstname,
'lastname' => $fields->lastname,
'nationality' => $fields->nationality,
'occupation' => $fields->occupation,
'address' => $fields->address,
'city' => $fields->city,
'state' => $fields->state,
'zipcode' => $fields->zipcode,
'phoneno' => $fields->phoneno,
'dob' => $fields->dob,
'gender' => $fields->gender,
'martial_status' => $fields->martial_status,
'user_image' => $fields->user_image,
]);
Account::create([
'accno' => $user->accno,
'username' => $user->username,
]);
return $user;
}
then storing the data using my registrationController:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use App\Http\Requests\RegistrationRequest;
use App\Traits\RegisterUser;
class RegistrationController extends Controller
{
use RegisterUser;
public function show()
{
return view('auth/register');
}
public function register(RegistrationRequest $requestFields)
{
//calling the registerUser method inside RegisterUser trait.
$user = $this->registerUser($requestFields);
return redirect('/login');
}
}
but when I register the user, the data is only saved in the create_user_table and return a 404 page not found error. How can I save the data to the selected table and redirect to the login page?
As fa as i can see this is not true for foreign key relations in User Model
public function profiles()
{
return $this->hasOne(profiles::class);
}
public function accounts()
{
return $this->hasOne(accounts::class);
}
public function transactions()
{
return $this->hasMany(transactions::class);
}
it should be as follows;
public function profiles()
{
return $this->hasOne(Profile::class);
}
public function accounts()
{
return $this->hasOne(Account::class);
}
public function transactions()
{
return $this->hasMany(Transaction::class);
}
Try this
public function registerUser($fields)
{
$user = User::create([
'username' => $fields->username,
'accno' => $this->generateAccountNumber(),
'email' => $fields->email,
'password' => $fields->password = bcrypt(request('password')),
'roles' => $fields->roles,
'activation_code' => $this->generateToken()
]);
$user->userprofile =Profile::create([
'accno' => $user->accno,
'username' => $user->username,
'acc_type' => $fields->acc_type,
'firstname' => $fields->firstname,
'lastname' => $fields->lastname,
'nationality' => $fields->nationality,
'occupation' => $fields->occupation,
'address' => $fields->address,
'city' => $fields->city,
'state' => $fields->state,
'zipcode' => $fields->zipcode,
'phoneno' => $fields->phoneno,
'dob' => $fields->dob,
'gender' => $fields->gender,
'martial_status' => $fields->martial_status,
'user_image' => $fields->user_image,
]);
$user->useraccount = Account::create([
'accno' => $user->accno,
'username' => $user->username,
]);
return $user;
}
If you are using a voyager package then there is a log file where you will find error messages that can help you understand the exact problem .
the log interface existe in voyager admin panel in :
Tools => Compass => Logs
look at this image :
Try this in your User model
protected static function boot()
{
protected static function boot()
parent::boot();
static::created(function ($user){
$user->profiles()->create([
'accno' => $user->accno,
'username' => $user->username,
.... => ....
]);
$user->accounts()->create([
'accno' => $user->accno,
'username' => $user->username,
]);
});
}
An error 404 is often a problem with a route.
As requested by Christos Lytras in a comment, we need to see your routes/web.php and the output of php artisan route:list to verify.
I believe the redirect in your registrationController is not pointing to a valid url:
return redirect('/login');
Without seeing your routes I can't say for sure but if your login route name is defined, you can do:
return redirect()->route('login');
Please share your routes file to confirm.
create() method is used for mass assignment. you will need to specify either a fillable or guarded attribute on the model. So check the fillable attribute on Profile and Account Model.

Auth::attempt always return false and I don't know why

public function login( Request $request ) {
$fields = [
'email' => $request->email,
'password' => $request->password,
];
$access = Auth::attempt( $fields );
echo $access;
if ( $access ) {
$user = Auth::teacher();
$token = $user->createToken('MyApp')->accessToken;
return response()->json( [
"message" => "Login realizado com sucesso!",
"data" => [
'user' => $user,
'token' => $token
]
], 200 );
} else {
return response()->json( [
"message" => "Email ou senha inválidos!",
"data" => null,
"return" => $access,
], 401 );
}
I have this function to login, I am try with a Model Teacher, but always auth::attempt gave me false, but if I am try with User Model the result is true.
My Model Teacher
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;
use App\Student;
use App\Rating;
use App\Commentary;
use App\User;
class Teacher extends Authenticatable
{
use Notifiable;
use HasApiTokens;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function students(){
return $this->belongsToMany('App\Student')->withTimestamps();
}
public function ratings(){
return $this->hasMany('App\Rating');
}
public function commentaries(){
return $this->hasMany('App\Commentary');
}
public function updateTeacher(Request $req){
$validator = Validator::make($request->all(),[
]);
if($validator->fails()){
return response()->json($validator->errors());
}
if ($req->name)
$this->name = $req->name;
if ($req->email)
$this->email = $req->email;
if ($req->password)
$this->password = $req->password;
if ($req->number)
$this->number = $req->number;
if ($req->birth)
$this->birth = $req->birth;
if ($req->CPF)
$this->CPF = $req->CPF;
if ($req->lesson_price)
$this->lesson_price = $req->lesson_price;
if ($req->rent_price)
$this->rent_price = $req->rent_price;
if ($req->description)
$this->description = $req->description;
if ($req->district)
$this->district = $req->district;
if ($req->zone)
$this->zone = $req->zone;
if ($req->instruments)
$this->instruments = $req->instruments;
if ($req->certification)
$this->certification = $req->certification;
$this->save();
}
public function listTeachers(){
$paginator = Teacher::paginate(10);
return response()->json([$paginator]);
}
public function showTeacher($id){
$teacher = Teacher::findOrFail($id);
return response()->json([$teacher]);
}
}
My Model User
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;
class User extends Authenticatable
{
use Notifiable;
use HasApiTokens;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
So i am think that Teacher have the same functions and most operations like User, thus the function auth::attempt should works with Teacher.
add teacher model to the guard in config/auth.php and then use
Auth::guard('teacher')->attempt($credentials)
'guards' => [
'user' => [
'driver' => 'session',
'provider' => 'users',
],
'teacher' => [
'driver' => 'session',
'provider' => 'teachers',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'teachers' => [
'driver' => 'eloquent',
'model' => App\Teacher::class,
],
],
Default Laravel authentication only works with User model. It is specified in config/auth.php. If you want to use another model for authentication you can just change in auth.php.
If you want multiple models to be used for Authentication, for example, both User and Teacher , you need to look into Guards in Laravel.
Here is a link to a tutorial which explains this technique.
HOW TO USE MULTIPLE AUTHENTICATION GUARDS IN A LARAVEL APP

email_verified_at automatically set while sending verification email in laravel 5.8

enter image description herein my laravel app, i have problem that is when i register user laravel automatically fills email_verified_at column in user table and redirects to dashboard. it automatically verifies without clicking on link. I do not know why this is filling this column value while sending verification email.
this is register controller
protected $redirectTo = 'email/verify';
public function __construct()
{
$this->middleware('guest');
}
protected function validator(array $data)
{
return Validator::make($data, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'alpha_num', 'min:8', 'confirmed'],
]);
}
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
this is user model
class User extends Authenticatable implements MustVerifyEmail
{
use Notifiable;
protected $fillable = [
'name', 'email', 'password'
];
protected $hidden = [
'password', 'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
}
this is verification controller
use VerifiesEmails;
protected $redirectTo = '/dashboard';
public function __construct()
{
$this->middleware('auth');
$this->middleware('signed')->only('verify');
$this->middleware('throttle:3,1')->only('verify', 'resend');
}
this is route file
Auth::routes(['verify' => true]);
Route::group(['prefix'=>'dashboard','middleware' => ['auth','verified']],function () {
Route::get('/','dashboard\DashboardController#index')->name('dashboard-home');
});
this is login controller
class LoginController extends Controller
{
use AuthenticatesUsers{
logout as performLogout;
}
protected $redirectTo = '/dashboard';
public function __construct()
{
$this->middleware('guest')->except('logout');
$this->middleware('prelogoutaction',['only' => 'logout']);
$this->middleware('postloginaction',['only' => 'login']);
}
public function logout(Request $request){
$this->performLogout($request);
return redirect()->route('web-home');
}
}
both email_verified_at and created_at are same.
please help...
So after all the discussion over comments and after seeing the code
we can conclude that the issue is on the database end which set the verification date and it is automatically filled up because of the attribute ON UPDATE CURRENT_TIMESTAMP() whenever the record is created.

Laravel Authentication: The 'guest' method of the default web guard redirects other logged in guards

I have a custom guard named 'customers'.
Config/Auth.php
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
'customers' => [
'driver' => 'session',
'provider' => 'customers',
],
],
The login page of the default guard has a method to redirect the already logged in users of the that guard.
LoginController.php
public function __construct()
{
$this->middleware('guest')->except('logout');
}
But this redirects the logged in users of other guards too.
I have tried modifying the abouve method
public function __construct()
{
$this->middleware('guest:web')->except('logout');
}
But no results.
My customer model
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Notifications\CustomerResetPasswordNotification;
class Customer extends Authenticatable
{
use SoftDeletes;
use Notifiable;
protected $guard = 'customers';
use \Askedio\SoftCascade\Traits\SoftCascadeTrait;
protected $dates = ['deleted_at'];
protected $guarded = ['id'];
protected $softCascade = ['address'];
protected $hidden = ['password', 'remember_token'];
public function address()
{
return $this->hasMany(AddressBook::class);
}
public function ipaddress()
{
return $this->hasMany(IpAddress::class);
}
public function sendPasswordResetNotification($token)
{
$this->notify(new CustomerResetPasswordNotification($token));
}
public function coupons()
{
return $this->belongsToMany(Coupon::class);
}
}
Use this
public function __construct()
{
$this->middleware('auth:customer')->except('logout');
}

Categories