简体   繁体   中英

Laravel - SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect datetime value: '1616818311712'

I am new to Laravel and I am using version 5.8.38. I am using its Authentication system in my project, but whenever I use the "Reset Password" option, after I enter the email address where the Reset Password email is going to be sent to. I get the following error:

SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect datetime value: '1616819329600' for column `proyectolaravel`.`password_resets`.`created_at` at row 1 (SQL: insert into `password_resets` (`email`, `token`, `created_at`) values (andre_jack@hotmail.com, $2y$10$kCwg25dPXcmsn4msea37FOD3ocpHHv1.q1A89dNfbMDADsOnNOole, 1616819329600))

I have been trying to fix this problem but I have not been able to find anything related to this error regarding password_resets for Laravel.

I do not know why the date value for "created_at" is being saved as "1616819329600", and I wonder if there is any way to solve this. For what I have researched, I think the problem relays in the file DatabaseTokenRepository at vendor\laravel\framework\src\Illuminate\Auth\Passwords\DatabaseTokenRepository.php but I know that I should not manipulate those files.

If it is of any use, I share with you the content of that file:

<?php

namespace Illuminate\Auth\Passwords;

use Illuminate\Support\Str;
use Illuminate\Support\Carbon;
use Illuminate\Database\ConnectionInterface;
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;

class DatabaseTokenRepository implements TokenRepositoryInterface
{
    /**
     * The database connection instance.
     *
     * @var \Illuminate\Database\ConnectionInterface
     */
    protected $connection;

    /**
     * The Hasher implementation.
     *
     * @var \Illuminate\Contracts\Hashing\Hasher
     */
    protected $hasher;

    /**
     * The token database table.
     *
     * @var string
     */
    protected $table;

    /**
     * The hashing key.
     *
     * @var string
     */
    protected $hashKey;

    /**
     * The number of seconds a token should last.
     *
     * @var int
     */
    protected $expires;

    /**
     * Create a new token repository instance.
     *
     * @param  \Illuminate\Database\ConnectionInterface  $connection
     * @param  \Illuminate\Contracts\Hashing\Hasher  $hasher
     * @param  string  $table
     * @param  string  $hashKey
     * @param  int  $expires
     * @return void
     */
    public function __construct(ConnectionInterface $connection, HasherContract $hasher,
                                $table, $hashKey, $expires = 60)
    {
        $this->table = $table;
        $this->hasher = $hasher;
        $this->hashKey = $hashKey;
        $this->expires = $expires * 60;
        $this->connection = $connection;
    }

    /**
     * Create a new token record.
     *
     * @param  \Illuminate\Contracts\Auth\CanResetPassword  $user
     * @return string
     */
    public function create(CanResetPasswordContract $user)
    {
        $email = $user->getEmailForPasswordReset();

        $this->deleteExisting($user);

        // We will create a new, random token for the user so that we can e-mail them
        // a safe link to the password reset form. Then we will insert a record in
        // the database so that we can verify the token within the actual reset.
        $token = $this->createNewToken();

        $this->getTable()->insert($this->getPayload($email, $token));

        return $token;
    }

    /**
     * Delete all existing reset tokens from the database.
     *
     * @param  \Illuminate\Contracts\Auth\CanResetPassword  $user
     * @return int
     */
    protected function deleteExisting(CanResetPasswordContract $user)
    {
        return $this->getTable()->where('email', $user->getEmailForPasswordReset())->delete();
    }

    /**
     * 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 Carbon];
    }

    /**
     * Determine if a token record exists and is valid.
     *
     * @param  \Illuminate\Contracts\Auth\CanResetPassword  $user
     * @param  string  $token
     * @return bool
     */
    public function exists(CanResetPasswordContract $user, $token)
    {
        $record = (array) $this->getTable()->where(
            'email', $user->getEmailForPasswordReset()
        )->first();

        return $record &&
               ! $this->tokenExpired($record['created_at']) &&
                 $this->hasher->check($token, $record['token']);
    }

    /**
     * Determine if the token has expired.
     *
     * @param  string  $createdAt
     * @return bool
     */
    protected function tokenExpired($createdAt)
    {
        return Carbon::parse($createdAt)->addSeconds($this->expires)->isPast();
    }

    /**
     * Delete a token record by user.
     *
     * @param  \Illuminate\Contracts\Auth\CanResetPassword  $user
     * @return void
     */
    public function delete(CanResetPasswordContract $user)
    {
        $this->deleteExisting($user);
    }

    /**
     * Delete expired tokens.
     *
     * @return void
     */
    public function deleteExpired()
    {
        $expiredAt = Carbon::now()->subSeconds($this->expires);

        $this->getTable()->where('created_at', '<', $expiredAt)->delete();
    }

    /**
     * Create a new token for the user.
     *
     * @return string
     */
    public function createNewToken()
    {
        return hash_hmac('sha256', Str::random(40), $this->hashKey);
    }

    /**
     * Get the database connection instance.
     *
     * @return \Illuminate\Database\ConnectionInterface
     */
    public function getConnection()
    {
        return $this->connection;
    }

    /**
     * Begin a new database query against the table.
     *
     * @return \Illuminate\Database\Query\Builder
     */
    protected function getTable()
    {
        return $this->connection->table($this->table);
    }

    /**
     * Get the hasher instance.
     *
     * @return \Illuminate\Contracts\Hashing\Hasher
     */
    public function getHasher()
    {
        return $this->hasher;
    }
}

Any help will be highly appreciated!

You have to use like this

use Carbon/Carbon;

Add above in header section

protected function getPayload($email, $token)
{
    return ['email' => $email, 'token' => $this->hasher->make($token), 'created_at' => Carbon::now()->format('Y-m-d H:i:s')];
}

I FINALLY figured it out, the created_at field was trying to be saved with the value of 1616819329600 because there was a conflict between Laravel's original Password Service Provider, and Jenssegers' Password Service Provider (which was being used before I migrated my project from MongoDB to MySQL) at "config/app.php".

So, when my problem was ocurring, my app.php file looked like this:

(...)

/*
* Package Service Providers...
*/

Jenssegers\Mongodb\MongodbServiceProvider::class,
Jenssegers\Mongodb\Auth\PasswordResetServiceProvider::class,

(...)

And finally, after the fix, I just deleted those lines of code and my app.php now looks this way:

(...)

/*
* Package Service Providers...
*/


/*
* Application Service Providers...
*/

(...)

I guess you could say that the exact reason this happened is that you shouldn't use two package service providers ending with the same name at the same file, as you can see in the following example:

Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
Jenssegers\Mongodb\Auth\PasswordResetServiceProvider::class,

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM