how to hash a password laravel 5.2 model create - laravel

I'm creating admin user via model and it saving record successfully but password is not being hashed as follows:
$request->password = bcrypt($request->input('password'));
Admin::create($request->except('_token'));

you can not modify $request properties like that.
Give it a try:
$input = $request->except('_token');
$input['password'] = bcrypt($input['password']);
Admin::create($input);
OR, handle it in your Admin Model
public function setPasswordAttribute($value)
{
$this->attributes['password'] = bcrypt($value);
}
Then you can
Admin::create($request->except('_token'));

Take a look at Laravel's Hashing documentation. It shows that you should be hashing any strings like so:
Hash::make($request->newPassword)
However looking at your code, i'd say this issue is actually the fact you're trying to modify the request $request->password, this is not going to work how you expect. Look at your Admin model class and see what the code is expecting, perhaps this is already in built if you pass the correct arguments.

Related

Laravel Automatic resource CRUD

What patterns can I use for 'automatic' resource CRUD operations for given Models in Laravel?
Say I have two models SomeModel and SomeRelatedModel where some_related_model.some_model_id is an FK to SomeModel.
The standard method on the SomeModelController for handling the create POST /api/someModel might look like this:
public function store(Request $request)
{
$user = Auth::guard('api')->user();
$data = $request->get('data');
$data['user_id'] = $user->id;
$someModel = SomeModel::create($data);
// has this request been made with the data for the
// related model? If so create this too.
if($data['relatedModel']){
SomeRelatedModel::create(array_merge(
['some_model_id' => $someModel->id]
$data['relatedModel']
));
}
// has this request been made expecting to get related
// models back in the response? If so load these
if($request->has('with')){
$someModel->load($request->get('with'));
}
return (new PostResource($post))
->toResponse($request)
->setStatusCode(201);
}
This works but is very verbose and for models with a sub-sub relation would need changing further. Similar work will need to be done for the other endpoints for all resources.
Is there a more versatile (or tidy) pattern using out-of-the box classes to get a similar effect?
Have a look at Laravel Orion. Fits your use case.

How to use Auth::login() without real authentication

I would like to use the "Laravel" Auth features.
I have a middleware which finds some data, extract :
$member = $this->memberService->getMemberRolesFromLdap($accessToken, $id);
$member is an array.
Just after this research, I would like to store this $member somewhere to retrieve some data later in some other classes. Like that :
$roles = Auth::user()->roles;
So I thought it was a good opportunity to use these Auth features. But for the moment, I have this error :
Symfony\Component\Debug\Exception\FatalThrowableError: Argument 1 passed to Illuminate\Auth\SessionGuard::login() must be an instance of Illuminate\Contracts\Auth\Authenticatable, array given
So if I understand, I must declare somewhere that $member uses (or is) an instance of Authenticable. And there I admit my limits.
Is it a good idea to use Auth features to do that, and if so, how can I do that?
I tried this. It works, but I am not sure if it is best practice:
$ldapData = $this->memberService->getMemberRolesFromLdap($accessToken, $id);
// login this member
$user = new User();
$user->ldapData = $ldapData;
Auth::login($user);
And now, I can manipulate the user like that:
Auth::user()->ldapData

Yii2 how to I get user from database in findIdentityByAccessToken method?

I need to set up JWT authentication for my Yii2 app. The authentication itself works fine, the token gets parsed and I can read it's data in my User model. But the problem is that I need to compare this data to a real user in my DB. So, I've got this method in the User model which extends ActiveRecord
public static function findIdentityByAccessToken($token, $type = null) {
$user = User::findOne(['ID' => 1]);
die(json_encode($user));
}
It's very simplified just to see that it finds a user. It does not and it always returns this:
{"id":null,"userLogin":null,"userPass":null,"userNicename":null,"userEmail":null,"userUrl":null,"userRegistered":null,"userActivationKey":null,"userStatus":null,"displayName":null}
The data is not populated. But if I do the same inside any controller, like so
class TokenController extends ActiveController
{
public $modelClass = 'app\models\User';
public function actionFind(){
return User::findOne(['ID' => 1]);
}
}
It works great and I get the User object populated with correct data.
Is it possible to get user from not within an ActiveController class?
Well, I don't know exactly what is wrong with this line here die(json_encode($user));
But it actually finds and populates the user and I can access it later via
Yii::$app->user->identity
so I can also blindly compare its ID and password to the real ones here

Make email authentication case insensitive in Laravel 5.7

I use the default email authentication in Laravel 5.7.3 (just updated from 5.4) with a sqlite DB. At login my email address gets validated case sensitive which is not what I want. It should be allowed to login with "JohnDoe#foobar.com" as well as "johndoe#foobar.com".
I've tried to add an accessor at my user model to always lowercase the database value.
public function getEmailAttribute($value) {
return strtolower($value);
}
But this one doesn't seem to be used by Auth at all. Additionally I don't know where to change the user input in the incomming request to lower case.
Is there a simple config case sensitive switch? Or where do I need to change/add scripts?
Thanks for your support
Daniel
Your accessor should be fine, but you should make sure that you also lowercase the given value, e.g. In your controller:
Assuming that you're using the default LoginController shipped from Laravel:
I overwrote the credentials method from AuthenticatesUsers in App\Http\Controllers\Auth\LoginController
protected function credentials(Request $request)
{
$credentials = [
$this->username() => strtolower($request->get($this->username())),
"password" => $request->get("password")
];
return $credentials;
}
This works fine, when all emails stored in the database are already stored all-lowercase. If you're starting from scratch you can enforce the emails to be stored lowercase by default. Just implement the following mutator in your App\User:
public function setEmailAttribute($value)
{
$this->attributes['email'] = strtolower($value);
}
If you have stored mixed-case email already, you can update all emails to lowercase emails using this query:
UPDATE users SET email = LOWER(email);
But this still feels kind of incomplete and you maybe don't want to manipulate your data this way. I am pretty much sure that there are more possibilities to make this happen but unfortunately I am not able to dig into this further for now. However my next attempt would be to extend/write a custom UserProvider.
You have to call getEmailAttribute(/your email here/)
before login and signup like this
$request->email = getEmailAttribute($request->get('email'));

How to handle data before delete from model in Laravel?

I have the following method:
public function destroy($id)
{
$id = \JWTAuth::parseToken()->authenticate();
$offer = Offer::findOrFail($id);
$offer->delete();
return response()->json(["offer" => $offer]);
}
How handle data before deleting? I need to check if user has permit to delete data or not
When you use the authenticate() method, the user model is retrieved so it means the id you have is not an id but a User. Have you checked the documentation of JWT Because first and foremost you have to retrieve the user and this is sufficient:
$user = \JWTAuth::parseToken()->authenticate();
Then if you have a field for example in your users table to tell if the user have the right say admin which can be 1 or 0 then you can do the following:
if($user->admin == 1)
{
$offer = Offer::findOrFail(1); //say id
$offer->delete();
return response()->json(["offer" => $offer]);
}
return response()->json(['error' => 'you dont have the right to delete this'], 403);
Just a little scratch on the idea, but my best advice is to do some searches on how JWT is implemented, I am pretty sure you will find tons of them online.
I would recommend using the Model's delete event:
https://github.com/laravel/framework/blob/5.2/src/Illuminate/Database/Eloquent/Model.php#L1122
and handle it.
This will guarantee that if you use the delete method on a model, you always check permissions.

Resources