Reputation: 99
I wonder what wrong in my code that I can't protected 2 input username and password
In my controller:
class AccountsController extends \BaseController {
...
public function store()
{
$date = new \DateTime;
$input['updated_at']=$date;
$input['created_at']=$date;
$input['username']=Input::get("username", "");
$input['password']=Input::get("password", "");
$input['sex']=Input::get("sex", "");
$input['dob']=Input::get("dob", "");
$input['dob']= date("Y-m-d", strtotime($input['dob']));
$v=Validator::make($input, Account::$register_rules);
$input['password']=Hash::make($input['password']);
if($v->passes()){
DB::table('accounts')->insert($input);
}
//return Redirect::route('text.index');
}
...
}
In my model:
class Account extends \Eloquent {
protected $guarded = array('username', 'password');
public static $register_rules=array(
'username' => 'required|min:4|max:20|unique:accounts',
'password' => 'required|alpha_num|min:6',
'sex' => 'required|in:f,m',
'dob' => 'required|date_format:Y-m-d'
);
}
In my app/view
...
{{ Form::open(array('route'=>'account.store')) }}
<table>
<tr>
<td>{{ Form::label('username', 'Username') }}</td>
<td>{{ Form::text('username') }}</td>
</tr>
<tr>
<td>{{ Form::label('password', 'Password') }}</td>
<td>{{ Form::password('password') }}</td>
</tr>
<tr>
<td>{{ Form::label('confirm_password', 'Confirm Password') }}</td>
<td>{{ Form::password('confirm_password', array('id'=>'confirm_password')) }}</td>
</tr>
<tr>
<td>{{ Form::label('sex', 'Sex') }}</td>
<td>
{{ Form::radio('sex', 'f', true) }}{{ Form::label('Female') }}
{{ Form::radio('sex', 'm') }}{{ Form::label('Male') }}
</td>
</tr>
<tr>
<td>{{ Form::label('dob', 'Date of Birth') }}</td>
<td>
{{Form::text('dob', '', array('id' => 'dob'))}}
</td>
</tr>
<tr>
<td></td>
<td>{{ Form::submit('Register', array('id' => 'submit')) }}</td>
</tr>
</table>
{{ Form::close() }}
...
Even though I defined guarded these two fields they are still saved in the database.
Upvotes: 0
Views: 2911
Reputation: 146191
Actually you are not using Eloquent ORM
and hence the following code guards mass assignment of Eloquent
models, for example using Model::create(Input::all())
method you may create a new Account
in the database like:
$account = Account::create(Input::all());
In your case, you are not using Eloquent
model, instead you are using insert
method using DB::('accounts')->insert($input)
which is a feature of Query builder
class (It's an instance of Illuminate\Database\Query\Builder
).
So, if you use the Eloquent ORM
then the features of Eloquent
will be used. In this case, use of Model::save()
is not a mass assignment but create()
uses the mass assignment because when creating a new model, you may pass an array
of attributes to the model constructor. These attributes are then assigned to the model via mass-assignment and create
accepts an array
of attributes and then initializes the model using new static($attributes)
, for example, this is the create
method:
public static function create(array $attributes)
{
$model = new static($attributes);
$model->save();
return $model;
}
So, if you manually initiate a model using something like this:
$account = new Account(Input::all()); // Mass assignment through constructor
$account->save();
This will be a mass assignment. In this case you need to create the Account
model by extending the Eloquent
like this (You already have one):
class Account extends Eloquent {
// Protect mass assignment
protected $guarded = array('username', 'password');
//...
}
You may read more about Mass Assignment on Laravel
website.
Upvotes: 2
Reputation: 14620
You are not using the Eloquent ORM. If you don't use the ORM you can't expect any of its features to be used.
DB::table('accounts')->insert($input);
Should be
$account = new Account($input);
$account->save():
// This is mass assigning model attributes
Now you will see that your guarded attributes are properly guarded. It is recommended that you do not pass raw input data into a model that has guarded attributes set without defining them either as fillable or making sure you specifically sanitise the data.
So your code would become something similar to the below.
$model = new Account();
$model->username = Input::get('username', '');
// etc ...
$validator = Validator::make($model->toArray(), $rules);
if ( ! $validator->fails() )
$model->save();
Upvotes: 1