Laravel-mongodb: Reset Password not working Laravel 5.4.

Created on 20 Feb 2017  路  13Comments  路  Source: jenssegers/laravel-mongodb

Hi Guys,

I've tried to implement password reset, also with 'Jenssegers\Mongodb\Auth\PasswordResetServiceProvider::class' , but there are certain mistakes

First: Jenssegers\Mongodb\Auth\PasswordBrokerManager::class is big mistake with missing parameter in function, should look like this :

protected function createTokenRepository(array $config)
{
return new DatabaseTokenRepository(
$this->app['db']->connection(),
$this->app['hash'], // this is missing
$config['table'],
$this->app['config']['app.key'],
$config['expire']
);
}

And after that is problem with: Cannot use object of type MongoDB\BSON\UTCDateTime as array

It would be helpful to fix it,

Thanks

bug fixed

Most helpful comment

My dirty hack for reset issues:

Add the following to Auth/ForgotPasswordController and Auth/ResetPasswordController to make it work (requires php 7):

/**
 * Get the broker to be used during password reset.
 *
 * TODO: remove this method once Jenssegers\Mongodb reset password issues are fixed
 *
 * @return \Illuminate\Contracts\Auth\PasswordBroker
 */
public function broker()
{
    return new class(app()) extends \Jenssegers\Mongodb\Auth\PasswordBrokerManager {

        protected function createTokenRepository(array $config)
        {
            $c = $this->app['db']->connection();
            $h = $this->app['hash'];
            $t = $config['table'];
            $k = $this->app['config']['app.key'];
            $e = $config['expire'];

            return new class($c, $h, $t, $k, $e) extends \Illuminate\Auth\Passwords\DatabaseTokenRepository {

                protected function getPayload($email, $token)
                {
                    return ['email' => $email, 'token' => $this->hasher->make($token), 'created_at' => new UTCDateTime(time() * 1000)];
                }

                protected function tokenExpired($token)
                {
                    // Convert UTCDateTime to a date string.
                    if ($token instanceof UTCDateTime) {
                        $date = $token->toDateTime();
                        $date->setTimezone(new DateTimeZone(date_default_timezone_get()));
                        $token = $date->format('Y-m-d H:i:s');
                    } elseif (is_array($token) and isset($token['date'])) {
                        $date = new DateTime($token['date'], new DateTimeZone(isset($token['timezone']) ? $token['timezone'] : 'UTC'));
                        $date->setTimezone(new DateTimeZone(date_default_timezone_get()));
                        $token = $date->format('Y-m-d H:i:s');
                    }

                    return parent::tokenExpired($token);
                }
            };
        }
    };
}

As you see there are 2 issues:

  • token should be stored as a hash ($this->hasher->make($token))
  • tokenExpired gets $token which doesn't require $token['created_at'] anymore

All 13 comments

Same problem here.. Any solution?

Same problem here

Any solution?

Same problem here

Same issue here as well. Any fix planned?

---Updated with Solution---

I was able to make this work by making some changes to the Moloquent PasswordBrokerManager.php and DatabaseTokenRepository.php files:

PasswordBrokerManager.php:

namespace Moloquent\Auth;

use Illuminate\Auth\Passwords\PasswordBrokerManager as BasePasswordBrokerManager;

class PasswordBrokerManager extends BasePasswordBrokerManager
{

    protected function createTokenRepository(array $config)
    {

        $key = $this->app['config']['app.key'];

        if (\Illuminate\Support\Str::startsWith($key, 'base64:')) {
            $key = base64_decode(substr($key, 7));
        }

        $connection = isset($config['connection']) ? $config['connection'] : null;

        return new DatabaseTokenRepository(
            $this->app['db']->connection(),
            $this->app['hash'],
            $config['table'],
            $this->app['config']['app.key'],
            $config['expire']
        );
    }

}

DatabaseTokenRepository.php:

namespace Moloquent\Auth;

use DateTime;
use DateTimeZone;
use Illuminate\Auth\Passwords\DatabaseTokenRepository as BaseDatabaseTokenRepository;
use MongoDB\BSON\UTCDateTime;

class DatabaseTokenRepository extends BaseDatabaseTokenRepository
{
    /**
     * Build the record payload for the table.
     *
     * @param string $email
     * @param string $token
     *
     * @return array
     */
    protected function getPayload($email, $token)
    {
        return ['email' => $email, 'token' => $this->hasher->make($token), 'created_at' => new UTCDateTime(time() * 1000)];
    }

    /**
     * Determine if the token has expired.
     *
     * @param array $token
     *
     * @return bool
     */
    protected function tokenExpired($createdAt)
    {
        // Convert UTCDateTime to a date string.
        if ($createdAt instanceof UTCDateTime) {
            $date = $createdAt->toDateTime();
            $date->setTimezone(new DateTimeZone(date_default_timezone_get()));
            $createdAt = $date->format('Y-m-d H:i:s');
         } elseif (is_array($createdAt) and isset($createdAt['date'])) {
            $date = new DateTime($createdAt['date'], new DateTimeZone(isset($createdAt['timezone']) ? $createdAt['timezone'] : 'UTC'));
            $date->setTimezone(new DateTimeZone(date_default_timezone_get()));
            $createdAt = $date->format('Y-m-d H:i:s');
        }

        return parent::tokenExpired($createdAt);
    }
}

See previous discussion on this issue here.

Test the above and working for me.

Try this solution but I still get the same error: Can not use object of type MongoDB \ BSON \ UTCDateTime as array

Someone else found some other solution for this error.

My dirty hack for reset issues:

Add the following to Auth/ForgotPasswordController and Auth/ResetPasswordController to make it work (requires php 7):

/**
 * Get the broker to be used during password reset.
 *
 * TODO: remove this method once Jenssegers\Mongodb reset password issues are fixed
 *
 * @return \Illuminate\Contracts\Auth\PasswordBroker
 */
public function broker()
{
    return new class(app()) extends \Jenssegers\Mongodb\Auth\PasswordBrokerManager {

        protected function createTokenRepository(array $config)
        {
            $c = $this->app['db']->connection();
            $h = $this->app['hash'];
            $t = $config['table'];
            $k = $this->app['config']['app.key'];
            $e = $config['expire'];

            return new class($c, $h, $t, $k, $e) extends \Illuminate\Auth\Passwords\DatabaseTokenRepository {

                protected function getPayload($email, $token)
                {
                    return ['email' => $email, 'token' => $this->hasher->make($token), 'created_at' => new UTCDateTime(time() * 1000)];
                }

                protected function tokenExpired($token)
                {
                    // Convert UTCDateTime to a date string.
                    if ($token instanceof UTCDateTime) {
                        $date = $token->toDateTime();
                        $date->setTimezone(new DateTimeZone(date_default_timezone_get()));
                        $token = $date->format('Y-m-d H:i:s');
                    } elseif (is_array($token) and isset($token['date'])) {
                        $date = new DateTime($token['date'], new DateTimeZone(isset($token['timezone']) ? $token['timezone'] : 'UTC'));
                        $date->setTimezone(new DateTimeZone(date_default_timezone_get()));
                        $token = $date->format('Y-m-d H:i:s');
                    }

                    return parent::tokenExpired($token);
                }
            };
        }
    };
}

As you see there are 2 issues:

  • token should be stored as a hash ($this->hasher->make($token))
  • tokenExpired gets $token which doesn't require $token['created_at'] anymore

any update ? @jenssegers

Thank you so much @mikekamornikov this solution working very well

it just need to add

use MongoDB\BSON\UTCDateTime;

also
new \DateTimeZone

if someone tried this solution and not worked , you just need to make a new reset request
example.com/password/reset
then
try the new token

Hey @mikekamornikov, I made all you wrote, but doesn't work.

I'm getting this error: DateTime::__construct(): Failed to parse time string (1539211570000) at position 11 (0): Unexpected character

Help me please!

@joerecra I need more context. Where does this error come from (trace)? The code above works for me for quiet some time (LV 5.6, php 7.1)

In Config/App.php replace Illuminate\Auth\Passwords\PasswordResetServiceProvider on Jenssegers\Mongodb\Auth\PasswordResetServiceProvider
In App/Http/Controllers/Auth/ResetPasswordController.php add use MongoDB\BSON\UTCDateTime;

Timezone: Europe/Moscow
Laravel: 5.7.*
Jenssegers/mongodb: "^3.4"

Was this page helpful?
0 / 5 - 0 ratings

Related issues

imrannazirbhat picture imrannazirbhat  路  3Comments

geofflancaster picture geofflancaster  路  3Comments

sebastiaanluca picture sebastiaanluca  路  3Comments

pirmax picture pirmax  路  3Comments

bastiendonjon picture bastiendonjon  路  3Comments