Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

habshady's avatar

Auth:attempt returns false

Hello, I have this "login" method in "loginConroller" that authenticate a user and redirects it to the dashboard if creds are correct but Auth::attempt returns false even if the email and password exists in the database. Here's the method login :

public function login(Request $request)
    {
        $credentials = $request->validate([
            'email' => ['required', 'email'],
            'password' => ['required'],
        ]);
        dd(Auth::attempt(['email' => $request->email, 'password' => $request->password])); //returns false

        if (Auth::attempt(['email' => $request->email, 'password' => $request->password])) {
            $request->session()->regenerate();

            return redirect()->intended('dashboard');
        }

        return back()->withErrors([
            'email' => 'The provided credentials do not match our records.',
        ]);
    }

This is model user.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;
use Laravel\Sanctum\HasApiTokens;
use jeremykenedy\LaravelRoles\Traits\HasRoleAndPermission;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;
    use HasRoleAndPermission;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [

        'username',
        'firstname',
        'lastname',
        'email',
        'password',
        'address',
        'city',
        'country',
        'postal',
        'about'
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    /**
     * Always encrypt the password when it is updated.
     *
     * @param $value
    * @return string
    */
    public function setPasswordAttribute($value)
    {
        $this->attributes['password'] = bcrypt($value);
    }
}

Here's my migration :

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('username');
            $table->string('firstname')->nullable();
            $table->string('lastname')->nullable();
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->string('address')->nullable();
            $table->string('city')->nullable();
            $table->string('country')->nullable();
            $table->string('postal')->nullable();
            $table->text('about')->nullable();
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
};

Here's my userseeder :

<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;

class UsersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $userRole = config('roles.models.role')::where('name', '=', 'User')->first();
        $adminRole = config('roles.models.role')::where('name', '=', 'Admin')->first();
        $permissions = config('roles.models.permission')::all();

        /*
         * Add Users
         *
         */
        if (config('roles.models.defaultUser')::where('email', '=', '[email protected]')->first() === null) {
            $newUser = config('roles.models.defaultUser')::create([
                'username'     => 'Admin',
                'email'    => '[email protected]',
                'password' => bcrypt('password'),
            ]);

            $newUser->attachRole($adminRole);
            foreach ($permissions as $permission) {
                $newUser->attachPermission($permission);
            }
        }

        if (config('roles.models.defaultUser')::where('email', '=', '[email protected]')->first() === null) {
            $newUser = config('roles.models.defaultUser')::create([
                'username'     => 'User',
                'email'    => '[email protected]',
                'password' => bcrypt('password'),
            ]);

            $newUser->attachRole($userRole);
        }
    }
}

Note: I'm using a package for handling roles and permissions in my project

0 likes
4 replies
Sergiu17's avatar
    public function setPasswordAttribute($value)
    {
        $this->attributes['password'] = bcrypt($value);
    }

i'm not 100% sure, but here is the problem, I think your password is hashed twice, one time by Laravel. Put your password hashing code somewhere else. Try ->

// when you create the user
$user = User::create([
	// ...
	'password' => Hash::make($request->password),
	// ...
]);
1 like
habshady's avatar

@Sergiu17 correct ! thanks, however to solve my problem is it good practice to just solve it by this ?

public function setPasswordAttribute($value)
    {
        $this->attributes['password'] = $value;
    }
Sergiu17's avatar
Sergiu17
Best Answer
Level 60

@habshady I don't think so, Laravel will not hash you password, it will call setPasswordAttribute twice for idk the reason why. You have to hash the password somewhere

1 like

Please or to participate in this conversation.