Зашифрованные поля модели Laravel не обновляются

#laravel #eloquent

Вопрос:

У меня возникли проблемы с обновлением полей github_oauth_token и github_oauth_refresh_token в моей User модели, в которых есть encrypted приведение. Все остальные поля обновляются нормально, и приведение работает должным образом, однако поля не будут сохранены в базе данных.

Модель пользователя

 namespace AppModels;

use AppMailEmailVerification;
use IlluminateSupportFacadesCrypt;
use IlluminateNotificationsNotifiable;
use IlluminateSupportFacadesValidator;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateFoundationAuthUser as Authenticatable;
use IlluminateSupportStr;
use IlluminateSupportFacadesMail;

class User extends Authenticatable
{
    use HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'first_name',
        'last_name',
        'email',
        'email_verification_token',
        'password',
        'github_oauth_token',
        'github_oauth_refresh_token',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
        'github_oauth_token' => 'encrypted',
        'github_oauth_refresh_token' => 'encrypted',
    ];

    /**
     * Set the user's github oauth token.
     *
     * @param string $value
     * @return void
     */
    public function setGithubOauthTokenAttribute($value)
    {
        $this->github_oauth_token = Crypt::encryptString($value);
    }

    /**
     * Set the user's github oauth refresh token.
     *
     * @param string $value
     * @return void
     */
    public function setGithubOauthRefreshTokenAttribute($value)
    {
        $this->github_oauth_refresh_token = Crypt::encryptString($value);
    }
}
 

Миграция пользователей

 use IlluminateDatabaseMigrationsMigration;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateSupportFacadesSchema;

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('first_name', 45);
            $table->string('last_name', 45);
            $table->string('email')->unique();
            $table->string('email_verification_token', 30)->nullable();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->string('github_oauth_token')->nullable();
            $table->string('github_oauth_refresh_token')->nullable();
            $table->rememberToken();
            $table->timestamps();
        });
    }

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

Способ управления

 public function handleGitHubCallback()
    {
        $gitHubUser = Socialite::driver('github')->user();

        $user = Auth::user();

        $user->github_oauth_token = $gitHubUser->token; // does not update
        $user->github_oauth_refresh_token = $gitHubUser->refreshToken; // does not update
        $user->first_name = 'Johnathan'; // updates fine
        
        $user->save();

        return redirect()->route('space.list.get')->with('success', Lang::get('messages.success_github_linked'));
    }
 

Ответ №1:

Проблема в User Model том, что .Вы приводите оба поля в свойство $cast

  protected $casts = [
        'email_verified_at' => 'datetime',
        'github_oauth_token' => 'encrypted',
        'github_oauth_refresh_token' => 'encrypted',
    ];
    
 

Так что нет необходимости добавлять мутаторы, поэтому удалите оба нижеперечисленных мутатора.

 public function setGithubOauthTokenAttribute($value)
{
    $this->github_oauth_token = Crypt::encryptString($value);
}

public function setGithubOauthRefreshTokenAttribute($value)
    {
        $this->github_oauth_refresh_token = Crypt::encryptString($value);
    }
 

Кроме того, если вы хотите использовать мутаторы, то у вас есть ошибка, она должна быть такой, как показано ниже

 public function setGithubOauthTokenAttribute($value)
    {
          $this->attributes['github_oauth_token ']= Crypt::encryptString($value);
    }

    public function setGithubOauthRefreshTokenAttribute($value)
        {
           $this->attributes['github_oauth_refresh_token ']= Crypt::encryptString($value);
        }
 

Комментарии:

1. Как вы и предлагали, я удалил мутаторы, но это не сработало и привело к тому же поведению. Я удалил поля из массива приведений, и это сработало (через мутаторы). В идеале я хотел бы просто использовать приведение шифрования, но в моем случае это, похоже, не работает…

2. я протестировал оба сценария, и они хорошо работают для меня .любой, который вы должны использовать. Либо актеры, либо мутаторы