3

I'm learning Laravel and when I tried inserting a user via artisan tinker with code below

$user = App\User::create([
    'username'=>'johnd',
    'first_name'=>'john',
    'last_name'=>'doe',
    'email'=>'[email protected]',
    'password'=>'thisShouldBeRandom',
    'shool_id'=>1,'type'=>'TEACHER'
]);

It throws this error:

Illuminate\Database\QueryException with message 'SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '' for key 'username' (SQL: insert into `users` (`first_name`, `last_name`, `type`, `updated_at`, `created_at`) values (john, doe, TEACHER, 2015-12-22 07:12:49, 2015-12-22 07:12:49))'

My model is:

namespace App;

use App\School;
use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\Access\Authorizable;
use League\Flysystem\Exception;
use URL;

class User extends Model implements AuthenticatableContract,
                                    AuthorizableContract,
                                    CanResetPasswordContract
{
    use Authenticatable, Authorizable, CanResetPassword;

    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'users';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['school_id', 'type'];

    /**
     * The attributes that are NOT mass assignable.
     *
     * @var array
     */
    protected $guarded = ['email', 'password', 'username'];
}

Also I noticed in the error it's only trying to insert the following columns into first_name, last_name, type, updated_at, created_at when I also included username in the array. Anything I'm missing?

EDIT

Looks like I have to add in username, email and the rest of the fields in the fillable property, however I'm thinking this might make it unsecure as it's fillable from a request. I think this is more appropriate with public data such as articles, posts, comments, etc. I'm thinking I'll go with a different approach for sensitive data, I could be wrong though. Again thanks for all the help!

P.S. When testing with artisan tinker make sure you close the instance and launch anew when you modify the code because it keeps the old compiled instance and doesn't see you changes. Took me a while to realise and caused a lot of headache.

4
  • But why do you think sending the username is unsecure? We already know everything we send is unsecure unless you are using an htpps connection. Commented Dec 22, 2015 at 7:59
  • @Amarnasan This statement in the docs A mass-assignment vulnerability occurs when a user passes an unexpected HTTP parameter through a request, and that parameter changes a column in your database you did not expect. or did I misunderstand it? Commented Dec 22, 2015 at 8:00
  • But that happens only if you blindly set the whole input array as the parameter fo the update. Commented Dec 22, 2015 at 8:02
  • 1
    So long as your user form has the CSRF token, then asking the user to enter their details when registering for example is perfectly normal. You can then do mass assignment, but before that you need to do some validation, which you can do manually or let Laravel help you laravel.com/docs/5.1/validation ps - if you are going to use Laravel for more than a 10 minute test project, I personally suggest you visit laracasts.com. Start with the free intro to Laravel Commented Dec 22, 2015 at 8:17

1 Answer 1

4

You need to remove 'username' from $guarded and put it in $fillable.

With 'username' in $guarded you are preventing the field to be set. So the database tries to create/update the field 'username' with empy default value, and it happens that you already have a row with empty username (because of the same error).

Actually, remove all column names you need to specify from $guarded and put them in $fillable, because I think you'll want to have 'email' and 'password' created/updated.

Sign up to request clarification or add additional context in comments.

4 Comments

But wouldn't that make it unsecure?
Correct, do the same for 'email', 'password' and any other column whose value you want to pass in to create method. Also, in your create method call, it's 'shool_id' which should be 'school_id'. And delete previous records from your table
@JohnnyQ It makes them 'unsecure' meaning you can update those fields. But you actually want to update those fields.
@Amarnasan I get it now. But again this approach looks like it makes username and password modifiable. I guess this isn't the right approach for sensitive data then? I think it should only be applied to public data like articles, posts, etc. By the way, many thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.