So create a new user and make a not of the hashed password. Now log in, and see if it changes on login. If it does, we would like to see your login code :)
Help me
So i have the default Auth of laravel 9 installed, but lately it does not work.
when i am register an user, it works. it will log in because of the Auth::login($user)
but then i log out and log in with the same credentials, but then i says 'These credentials do not match our records.'
the hash in the database is not correct, it was made with Hash::make($request->password), bycript() does the same thing.
so how do i fix this?
password = testtestha
this was stored in the database => $2y$10$mderQB5tIA.P0UmlpAeRzeCaeR0ppsIV37eZQJcceVpBHlk6PDH2S
but it needed to be => $2a$12$1pZfVCF3Zd3Ks4Do9Wo3F.x5ZV6FA5i2RTbsj/Tixs2eHNPsq/PEW
Before it was created $2y$10$hWXPI6/hiyKVvpn/vFFWm.mYGrE.P5nM3Yemp0C70mSPxjq/BKhG2
after $2y$10$Q0tRJnMd8t8l9isI.FAty.mg6UOnaeos9ESucTFmczoXXXkL8xBwq
so it does seem to change, but the before is still not good.
i did use the Auth default laravel plugin, so i did not write anything
@sarunama So this is a completely new installation without a single change?
<?php
namespace App\Http\Requests\Auth;
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
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'email' => ['required', 'string', 'email'],
'password' => ['required', 'string'],
];
}
/**
* Attempt to authenticate the request's credentials.
*
* @return void
*
* @throws \Illuminate\Validation\ValidationException
*/
public function authenticate()
{
$this->ensureIsNotRateLimited();
if (! Auth::attempt($this->only('email', 'password'), $this->boolean('remember'))) {
RateLimiter::hit($this->throttleKey());
throw ValidationException::withMessages([
'email' => __('auth.failed'),
]);
}
RateLimiter::clear($this->throttleKey());
}
/**
* Ensure the login request is not rate limited.
*
* @return void
*
* @throws \Illuminate\Validation\ValidationException
*/
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),
]),
]);
}
/**
* Get the rate limiting throttle key for the request.
*
* @return string
*/
public function throttleKey()
{
return Str::lower($this->input('email')).'|'.$this->ip();
}
}
@sarunama And the user model ?
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
use App\Models\Activity;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable, Cachable;
protected $fillable = [
'name',
'email',
'password',
];
protected $hidden = [
'password',
'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
public function offer()
{
return $this->hasMany(Offer::class);
}
public function user()
{
return $this->hasMany(Scroll::class);
}
public function activity()
{
return $this->hasMany(Activity::class);
}
public function receivesBroadcastNotificationsOn()
{
return 'users.'.$this->id;
}
}
but it needed to be
Incorrect, the hash produced for the same string will be different
>>> bcrypt('secret')
=> $2y$10$7OhM6KFsmz3KKhqbDLY9muBtyf/0NHe8E8e.xo3ivVMXyTFOBg9d2
>>> bcrypt('secret')
=> $2y$10$vkeYbIuhZmuEkdnX7.an0.wnQahzoM4iPF.JgQxl0R78S8J5a/PlC
You need to use Hash::check('secret', '$2y$10$vkeYbIuhZmuEkdnX7.an0.wnQahzoM4iPF.JgQxl0R78S8J5a/PlC'); to check if it is correct.
Probably you are double hashing the password? Is there a mutator on the User model to hash the password?
@tykus both return true
@sarunama both what?
@tykus the check is returning true. after i create the user, and just when i check it on a empty page with the credentials.
@sarunama what are you checking; and how are you checking it?
// before user created RETURN TRUE
dump(Hash::check($request->password, Hash::make($request->password)));
// After user created RETURN TRUE
dump(Hash::check('testtestha', $user->password));
@sarunama okay.
Are you doing anything non-standard; e.g. are you using something other than email and password fields on the login form?
@tykus Nope, its still de default login page from auth laravel
@sarunama check the password in the database:
Hash::check('testtestha', User::latest()->value('password'));
@tykus
its inside the default $request->authenticate(); function, here is something wrong. but i did not create this, its all main laravel stuff
@sarunama Which starter kit is this? UI? Breeze?
i dont know the starter kit, i think it is UI
this returns true
$user = \App\Models\User::find(11);
dd(\Illuminate\Support\Facades\Hash\Hash::check('testtestha', $user->password));
@sarunama if you are getting the These credentials do not match our records. error message, then the authentication has failed; I am trying to help you find out why...
If you manually try to authenticate; what happens?
\Auth::attempt(['email' => $user->email, 'password' => 'testtestha']);
@tykus i will try in about an hour, currently i am away
\Auth::attempt(['email' => '[email protected]', 'password' => 'testtestha']);
dd(auth()->user());
this works, it dumps out the user.
@tykus this returns true, not my code
public function authenticate()
{
$this->ensureIsNotRateLimited();
dd(Auth::attempt($this->only('email', 'password')));
if (! Auth::attempt($this->only('email', 'password'), $this->boolean('remember'))) {
RateLimiter::hit($this->throttleKey());
throw ValidationException::withMessages([
'email' => __('auth.failed'),
]);
}
RateLimiter::clear($this->throttleKey());
}
@sarunama what are the values of email and password at this point???
dd($this->only('email', 'password'));
the previuous was actually return true, i misspeld the login.
it returns
array:2 [▼
"email" => "[email protected]"
"password" => "testtestha"
]
the previuous was actually return true, i misspeld the login.
So, your problem is gone away?
no, problem is still there. is the dd dump returns true, i first said it was return false. but still i cant login
wait, i can now login... but there are no changes in my code (i have git running to see changes)
is it cache problem?
How would I know... I only have a window into the problem and the code you shared. There was nothing immediately apparent, so we step through the code to understand where an issue might occur. If you're all set, mark the thread closed.
well the issue is resolved in local development, but not in production, and since there is no change in code... there is no fix.
i will try to cache clear to see if that works
EDIT: not worked
@sarunama if you follow the same debugging steps in production; (i) check the Request email and password are as expected. Then Hash::check the database value against the Request password and so on.
Can you SSH into the server to work in a Tinker session?
@tykus yes i can go into tinker
Psy Shell v0.11.8 (PHP 8.1.10 — cli) by Justin Hileman
>>> \Hash::check('testtestha', 'y$sKlJI1D9cmSlDmFE/yEpQuzdGEVCjeqWZxtxrUKvzONl3PsTau6xm')
=> false
>>> \Hash::check('testtestha', \Hash::make('testtestha'))
=> true
>>> $user = /App/Models/User::find(14)
PHP Parse error: Syntax error, unexpected '/' on line 1
>>> $user = \App\Models\User::find(14)
=> App\Models\User {#4921
id: 14,
name: "test",
email: "[email protected]",
email_verified_at: null,
#password: "y$sKlJI1D9cmSlDmFE/yEpQuzdGEVCjeqWZxtxrUKvzONl3PsTau6xm",
#remember_token: null,
created_at: "2022-09-29 12:21:23",
updated_at: "2022-09-29 12:21:23",
}
>>> \Hash::check('testtestha', $user->password)
=> false
>>> $newUser = \App\Models\User::create(['name' => 'TestTest', 'email' => '[email protected]', 'password' => \Hash::make('testtestha')])
=> App\Models\User {#3970
name: "TestTest",
email: "[email protected]",
#password: "yLARACASTS_SNIPPET_PLACEHOLDERZI7i4dApwbTa63WDHx6jeKG20Nb5feM953HMEIXcVHlNXxXaxpMS",
updated_at: "2022-09-29 12:45:03",
created_at: "2022-09-29 12:45:03",
id: 15,
}
>>> \Hash::check('testtestha', $newUser->password)
=> true
after this i can login into the application, so something is wrong with register function then
public function store(Request $request)
{
$request->validate([
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'confirmed', Rules\Password::defaults()],
]);
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
event(new Registered($user));
Auth::login($user);
return redirect(RouteServiceProvider::HOME);
}
allright fixed it.
i replaced Hash::make with \Hash::make
it was using use Illuminate\Support\Facades\Hash;
@sarunama that is not a fix... because the Illuminate\Support\Facades\Hash class is the same class as \Hash because facade aliases
@sarunama not credible unfortunately; a happy coincidence perhaps.
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest;
use App\Providers\RouteServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class AuthenticatedSessionController extends Controller
{
/**
* Display the login view.
*
* @return \Illuminate\View\View
*/
public function create()
{
return view('auth.login');
}
/**
* Handle an incoming authentication request.
*
* @param \App\Http\Requests\Auth\LoginRequest $request
* @return \Illuminate\Http\RedirectResponse
*/
public function store(LoginRequest $request)
{
$request->authenticate();
$request->session()->regenerate();
return redirect()->intended(RouteServiceProvider::HOME);
}
/**
* Destroy an authenticated session.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy(Request $request)
{
Auth::guard('web')->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('/');
}
}
Please or to participate in this conversation.