# Cakephp 4 hashed password only work for 24 hours

**URL:** <https://discourse.cakephp.org/t/cakephp-4-hashed-password-only-work-for-24-hours/9010>\
**Category:** Need Help\
**Created:** [February 13, 2021, 4:47pm UTC](https://discourse.cakephp.org/t/cakephp-4-hashed-password-only-work-for-24-hours/9010 "2021-02-13T16:47:46Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![buchi](https://avatars.discourse-cdn.com/v4/letter/b/bcef8e/32.png) [@buchi](https://discourse.cakephp.org/u/buchi)\
**Post date:** [February 13, 2021, 4:47pm UTC](https://discourse.cakephp.org/t/cakephp-4-hashed-password-only-work-for-24-hours/9010/1 "2021-02-13T16:47:46Z")

</div>

Hi, I followed the steps from the cookbook and everything went fine. But after every max 24 hours, the login doens’t work for me.

I am not able to check, if something with my server went wrong, because I don’t know, how to check the differences of the hashcodes.

Am I the only one, who work with Cakephp 4 and hashed passwords and have this problem?

---

<div class="post-metadata">

**Author:** ![Jawfin](https://avatars.discourse-cdn.com/v4/letter/j/dbc845/32.png) [@Jawfin](https://discourse.cakephp.org/u/Jawfin)\
**Post date:** [February 14, 2021, 1:09am UTC](https://discourse.cakephp.org/t/cakephp-4-hashed-password-only-work-for-24-hours/9010/2 "2021-02-14T01:09:56Z")

</div>

Without code or anything its hard to say. I can say I haven’t had any difficulty though.

If I had to guess it may be an expired cookie you were relying on, and maybe some browser setting which was drawing from the cache. 24 hours really does smell like an expired cookie though! Try accessing the site from different devices and browsers to see if its the same everywhere.

I’d also suggest building the CMS demo [Content Management Tutorial - 4.x](https://book.cakephp.org/4/en/tutorials-and-examples/cms/installation.html) all the way through, and see if that stops working after 24 hours. In which case, you may need to be looking higher up at your stack: the PHP version, the server version (eg Apache), file level security & firewalls.

---

<div class="post-metadata">

**Author:** ![Zuluru](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/zuluru/32/1230_2.png) [@Zuluru](https://discourse.cakephp.org/u/Zuluru)\
**Post date:** [February 14, 2021, 4:40am UTC](https://discourse.cakephp.org/t/cakephp-4-hashed-password-only-work-for-24-hours/9010/3 "2021-02-14T04:40:36Z")

</div>

What does “hashed password only works for 24 hours” mean? After 24 hours you are no longer able to log in any more using that password? Or you log in and then 24 hours later it’s no longer remembering that you had logged in and asking you to do so again?

---

<div class="post-metadata">

**Author:** ![buchi](https://avatars.discourse-cdn.com/v4/letter/b/bcef8e/32.png) [@buchi](https://discourse.cakephp.org/u/buchi)\
**Post date:** [February 15, 2021, 11:11am UTC](https://discourse.cakephp.org/t/cakephp-4-hashed-password-only-work-for-24-hours/9010/4 "2021-02-15T11:11:58Z")

</div>

I rebuild the Tutorial and here is my Code:

Application.php

…  
use Authentication\AuthenticationService;  
use Authentication\AuthenticationServiceInterface;  
use Authentication\AuthenticationServiceProviderInterface;  
use Authentication\Identifier\IdentifierInterface;  
use Authentication\Middleware\AuthenticationMiddleware;  
…  
class Application extends BaseApplication implements AuthenticationServiceProviderInterface  
{  
…  
public function bootstrap(): void  
{  
…  
$this-\>addPlugin(‘Authentication’);  
…  
}

public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue  
{  
…  
-\>add(new AuthenticationMiddleware($this))  
…  
}  
public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface  
{  
$authenticationService = new AuthenticationService([  
‘unauthenticatedRedirect’ =\> ‘/myProject/users/login’,  
‘queryParam’ =\> ‘redirect’,  
]);  
$fields = [  
IdentifierInterface::CREDENTIAL\_USERNAME =\> ‘usr\_name’,  
IdentifierInterface::CREDENTIAL\_PASSWORD =\> ‘usr\_password’  
];

```
    // Load identifiers, ensure we check email and password fields
    /*$authenticationService->loadIdentifier('Authentication.Password', [
        'fields' => /*[
            'username' => 'usr_name',
            'password' => 'usr_password',
        ] $fields
    ]);*/

    // Load the authenticators, you want session first
    $authenticationService->loadAuthenticator('Authentication.Session');
    // Configure form data check to pick email and password
    $authenticationService->loadAuthenticator('Authentication.Form', [
        'fields' => /*[
            'username' => 'usr_name',
            'password' => 'usr_password',
        ]*/ $fields,
        'loginUrl' => '/adminHigh/users/login',
    ]);
    // // Load identifiers, ensure we check email and password fields
    $authenticationService->loadIdentifier('Authentication.Password', compact('fields'));

    return $authenticationService;
}

```

}

UserController

public function login() {

```
    $this->request->allowMethod(['get', 'post']);
    $result = $this->Authentication->getResult();     

    // regardless of POST or GET, redirect if user is logged in
    if ($result->isValid()) {       
        $redirect = $this->request->getQuery('redirect', [
                    'controller' => 'Courses',
                    'action' => 'index',
                ]);

        return $this->redirect($redirect);
       
    }
    // display error if user submitted and authentication failed
    if ($this->request->is('post') && !$result->isValid()) {
        $this->Flash->error(__('Invalid username or password'));
    }
}

```

User.php  
protected function \_setUsrPassword(string $password) : ?string  
{  
if (strlen($password) \> 0) {  
return (new DefaultPasswordHasher())-\>hash($password);  
}  
}

Everything works fine for about 24 hour, sometime more up to nearly 48 hours, and sometimes I get “Invalid password or Username” after less then 24 hours. I created a trigger, when my user table on the db is changing, but there is no changing…

---

<div class="post-metadata">

**Author:** ![Zuluru](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/zuluru/32/1230_2.png) [@Zuluru](https://discourse.cakephp.org/u/Zuluru)\
**Post date:** [February 15, 2021, 4:25pm UTC](https://discourse.cakephp.org/t/cakephp-4-hashed-password-only-work-for-24-hours/9010/5 "2021-02-15T16:25:38Z")

</div>

So, the person’s hashed password in the database is still the same 24 hours later, but now it won’t let them log in any more?

---

<div class="post-metadata">

**Author:** ![buchi](https://avatars.discourse-cdn.com/v4/letter/b/bcef8e/32.png) [@buchi](https://discourse.cakephp.org/u/buchi)\
**Post date:** [February 16, 2021, 1:44pm UTC](https://discourse.cakephp.org/t/cakephp-4-hashed-password-only-work-for-24-hours/9010/6 "2021-02-16T13:44:35Z")

</div>

Yes.  
But today I found something out. I have a second project, it is the same but my test-enviroment.  
It use the same database, and when I try to login there it worked and afterwards it workes also on my business enviroment…

I am so confused…

---

<div class="post-metadata">

**Author:** ![Zuluru](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/zuluru/32/1230_2.png) [@Zuluru](https://discourse.cakephp.org/u/Zuluru)\
**Post date:** [February 16, 2021, 5:07pm UTC](https://discourse.cakephp.org/t/cakephp-4-hashed-password-only-work-for-24-hours/9010/7 "2021-02-16T17:07:16Z")

</div>

If the hashed password is still the same, then there’s no good reason I can think of why it would stop being able to validate the provided password during the login process. If you’re using an old hash function with a salt value, and that salt is changing, that would do it. But otherwise…

---

<div class="post-metadata">

**Author:** ![Jawfin](https://avatars.discourse-cdn.com/v4/letter/j/dbc845/32.png) [@Jawfin](https://discourse.cakephp.org/u/Jawfin)\
**Post date:** [February 17, 2021, 2:08am UTC](https://discourse.cakephp.org/t/cakephp-4-hashed-password-only-work-for-24-hours/9010/8 "2021-02-17T02:08:13Z")

</div>

As Zuluru says, changing the salt/algorithm is the only thing which could break it within Cake. As I don’t know the guts of Cake it never hurts to purge the cache, just in case!  
`bin/cake cache clear_all`

Maybe also switching between http / https could break it perhaps? Like it’ll work via http:// but not https:// - so check that and use .htaccess (or equivalent) to force https.

Finally, check its not a password manager pulling the wrong password. Are you typing it every time? Also, remotely possible, a RTL language or accent characters + unicode in the password may make it inconsistent - and thus can’t even rely on copy/paste of the password as seen in clear text.

---

<div class="post-metadata">

**Author:** ![Zuluru](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/zuluru/32/1230_2.png) [@Zuluru](https://discourse.cakephp.org/u/Zuluru)\
**Post date:** [February 17, 2021, 4:20am UTC](https://discourse.cakephp.org/t/cakephp-4-hashed-password-only-work-for-24-hours/9010/9 "2021-02-17T04:20:32Z")

</div>

Good point about copy/paste. I’ve seen passwords fail because copy often grabs a space at the end of the highlighted text, and that will cause a password mismatch.

---

<div class="post-metadata">

**Author:** ![FinlayDaG33k](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/finlaydag33k/32/1049_2.png) [@FinlayDaG33k](https://discourse.cakephp.org/u/FinlayDaG33k)\
**Post date:** [February 17, 2021, 11:28am UTC](https://discourse.cakephp.org/t/cakephp-4-hashed-password-only-work-for-24-hours/9010/10 "2021-02-17T11:28:19Z")

</div>

> [@Jawfin](#):
>
> changing the salt/algorithm is the only thing which could break it within Cake

It shouldn’t, everything CakePHP uses `password_hash` and `password_verify` under the hood ([source](https://github.com/cakephp/cakephp/blob/master/src/Auth/DefaultPasswordHasher.php)).  
This means that the hash output will contain everything that’s needed:

- The algorithm used
- the salt
- the cost
- the hash itself

All `password_verify` does is take the first 3 parameters and runs them through the algorithm again then compares against the hash to see if they match.

Here’s some _illustrative_ code to show what PHP does to create the hash:

```php
$password = 'lamepassword';
$salt = 'lamesalt'; // Obviously this changes every time
$algo = 'sha256';
$rounds = 10;

function makeHash(string $data, string $salt, string $algo) {
  return hash($algo, $salt . $data);
}

$hash = $password;
for($round = 0; $round <= $rounds; $round++) {
  $hash = makeHash($password, $salt, $algo);
}

var_dump($algo . ':' . $rounds . ':' . $salt . ':' . $hash); // string(83) "sha256:10:lamesalt:75d640c3f13991f3932e1337c4878d87602abd01d56766da77fd0ff5b2cb936b"

```

Now for verification, it does the following (again, just for illustration):

```php
$password = 'lamepassword';
$hashStr = "sha256:10:lamesalt:75d640c3f13991f3932e1337c4878d87602abd01d56766da77fd0ff5b2cb936b";

list($algo, $rounds, $salt, $expectedHash) = explode(':', $hashStr);

function makeHash(string $data, string $salt, string $algo) {
  return hash($algo, $salt . $data);
}

$hash = $password;
for($round = 0; $round <= $rounds; $round++) {
  $hash = makeHash($password, $salt, $algo);
}

var_dump($hash === $expectedHash); // bool(true)

```

If the user were to give the wrong password, the expected hash and the hash we get from the input password won’t match up.  
The hash-string itself contains all data needed to do the verification, this is exactly to prevent cases where changing the algorithms in the code would prevent user login.

Developers can check whether the password needs a rehash using `\Cake\Auth\DefaultPasswordHasher#needsRehash`.

Additionally, salts should always be unique when hashing passwords.

- Salts are “unique” per password (to combat the effectiveness of so-called “[rainbow tables](https://en.wikipedia.org/wiki/Rainbow_table)”).
- Peppers are “unique” per app (but are rarely used when hashing passwords, atleast, in PHP).

> [@Jawfin](#):
>
> Maybe also switching between http / https could break it perhaps?

This also shouldn’t matter as the only difference here is how the browser and server will communicate.  
The data (and thus the password) will be the same, it’s just wrapped with some encryption so it is harder to intercept.  
To CakePHP, the data (and thus the password) it’ll see will be basically the same.

---

<div class="post-metadata">

**Author:** ![buchi](https://avatars.discourse-cdn.com/v4/letter/b/bcef8e/32.png) [@buchi](https://discourse.cakephp.org/u/buchi)\
**Post date:** [February 17, 2021, 1:18pm UTC](https://discourse.cakephp.org/t/cakephp-4-hashed-password-only-work-for-24-hours/9010/11 "2021-02-17T13:18:04Z")

</div>

Clearing the cache don’t help.

Today I found out, that the problem is the route:

$builder-\>connect(’/’, [‘controller’ =\> ‘Users’, ‘action’ =\> ‘login’]);

When I change it to:

$builder-\>connect(’/’, [‘controller’ =\> ‘Courses’, ‘action’ =\> ‘Index’]);

I will be redirected(because it is only accessable after the login) and my url is like:

“…/users/login?redirect=%2F” instead of “…/”

and now the login worked. It is a workaround which I can live with, but I don’t understand why this happen.

---

<div class="post-metadata">

**Author:** ![Zuluru](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/zuluru/32/1230_2.png) [@Zuluru](https://discourse.cakephp.org/u/Zuluru)\
**Post date:** [February 17, 2021, 9:32pm UTC](https://discourse.cakephp.org/t/cakephp-4-hashed-password-only-work-for-24-hours/9010/12 "2021-02-17T21:32:33Z")

</div>

There is stuff in the authentication plugin that validates that the login is happening on a valid URL. I’ve butted heads with it on occasion, and still don’t quite entirely understand how it all works, but that might be what you’re running into.

---

<div class="post-metadata">

**Author:** ![Jawfin](https://avatars.discourse-cdn.com/v4/letter/j/dbc845/32.png) [@Jawfin](https://discourse.cakephp.org/u/Jawfin)\
**Post date:** [February 18, 2021, 12:15am UTC](https://discourse.cakephp.org/t/cakephp-4-hashed-password-only-work-for-24-hours/9010/13 "2021-02-18T00:15:41Z")

</div>

Oooh, I remember now having a similar issue. I think the login page needed to be at the root of the website, it didn’t work nested in a sub-folder. I’ll dig around and check my notes / code, I may find the example where this happened, in which case I’ll edit this post. Whether that relates to the issue you had though, I cannot say. (I’ve also read it won’t work [well] if the Users table isn’t actually `users` and the fields in it aren’t `email` and `password` - just saying!)

---

<div class="post-metadata">

**Author:** ![Zuluru](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/zuluru/32/1230_2.png) [@Zuluru](https://discourse.cakephp.org/u/Zuluru)\
**Post date:** [February 18, 2021, 4:06am UTC](https://discourse.cakephp.org/t/cakephp-4-hashed-password-only-work-for-24-hours/9010/14 "2021-02-18T04:06:32Z")

</div>

None of this, though, explains the assertion that the login works just fine at first, and then stops working 24 hours later.

---

<div class="post-metadata">

**Author:** ![Jawfin](https://avatars.discourse-cdn.com/v4/letter/j/dbc845/32.png) [@Jawfin](https://discourse.cakephp.org/u/Jawfin)\
**Post date:** [February 18, 2021, 4:38am UTC](https://discourse.cakephp.org/t/cakephp-4-hashed-password-only-work-for-24-hours/9010/15 "2021-02-18T04:38:28Z")

</div>

Yea, I’m guessing the original login took, but a later redirect - perhaps after a 24 hour timeout by `config/app.cfg` `'Session' => ['timeout' => 1440],` stored in the cookie/session is where its falling apart.
