Change user password functionality -> password is saved, but I wont log in - cakephp-2.1

I'm writing a function to enable the users to change their password.
public function change_password() {
if ($this->request->is('post')) {
debug($this->request->data);
$tmpUsr = $this->User->find('first', array('conditions'=>array('user_id'=>$this->Auth->user('user_id'))));
debug($tmpUsr);
$tmpUsr['User']['password'] = AuthComponent::password($this->request->data['Change']['Confirmation']);
if ($this->User->save($tmpUsr)) {
debug("saved new password: " . $tmpUsr['User']['password']); // * after this debug is fired, the hash looks ok *
}
else {
debug("password was not saved");
}
}
}
Problem:
The saved password looks hashed, but I tried it and it looks like the values saved arent the correct hash.
In the database the saved hashed string is not correct altough after debugging it where I commented it looks ok..
Any ideas where could be a problem?
Im using the login functionality from cake tutorial (2.0)

Try :
$this->Auth->password($this->request->data['Change']['Confirmation']);
instead.
From the API docs "This method is intended as a convenience wrapper for Security::hash()"

I found the answer and it is just silly:
In the model there is a function beforeSave() where the hashing happens.
So the hashing happened twice (first time in the function change_password()) and then in beforeSave..
My mistake, sorry to take your time..

Related

Cookie-less Laravel sessions

We have a small quiz type functionality built in Laravel to be embedded in a site via an iframe served from a separate domain (to work around CMS limitations).
It uses sessions to keep track of the user's progress in the quiz. This doesn't work in Safari (Mac/iOS), I believe because Apple disable cookies issued from within an iframe.
Assuming that limitation is one we're stuck with, has anyone had any success making Laravel sessions cookie-less? I found this code on Github, which looks promising but is old enough (and incompatible with current Laravel) that I can't tell if it's going to be a solution.
In case it helps someone else, or anyone can see any silly errors in my code, this is what I did (an adaption of the Github code, to work in Laravel 9).
I extended StartSession and SessionServiceProvider (to use my new StartSession). I created an override for handleStatefulRequest in Start Session, and where it adds a cookie to the reponse (it calls addCookieToResponse) did this:
if ($request->cookies->get($session->getName())) {
$this->addCookieToResponse($response, $session);
}
else {
// Add session ID to header
$this->addIdentifierToResponse($response, $session);
}
That new function looks like this:
protected function addIdentifierToResponse(Response $response, Session $session)
{
if ($this->sessionIsPersistent($config = $this->manager->getSessionConfig())) {
$response->headers->set("X-Session-Token", $session->getId());
}
}
I also changed the getSession method to get the session ID from that newly set header (when no cookie found):
public function getSession(Request $request)
{
return tap($this->manager->driver(), function ($session) use ($request) {
if ($request->cookies->get($session->getName())) {
Log::debug('1. Set session ID from cookie');
$session->setId($request->cookies->get($session->getName()));
}
else if ($request->headers->get("X-Session-Token", $request->input("sess_id"))) {
$sessionToken = $request->headers->get("X-Session-Token", $request->input("sess_id"));
$session->setId($sessionToken);
}
});
}
I created a Github repo containing the whole thing.

KeystoneJS: How to set a field to receive randomly generated value?

I'm creating a model that I will use to authenticate users for API access, and I have a secret field where I want to store a Base64 encoded uuid/v4 generated value.
I went through the different field types and options, but still not seeing how I could achieve this.
Is there a way to hook in model instance creation, and set the value of my secret field ?
Yes, you can use the pre hooks.
In your situation, the basics would be:
AuthenticationModel.schema.pre("save", function(next) {
const secretValue = generateSecretValue();
this.secret = secretValue;
next();
});
That would go before your final AuthenticationModel.register(); in your model.js file.
This is how I set it up, also with the pre-save hook. My problem before was that I was getting the same random number again until I restarted the server.
Store.schema.pre('save', function (next) {
if (!this.updateId && this.isNew) {
// generates a random ID when the item is created
this.updateId = Math.random().toString(36).slice(-8);
}
next();
});
Using this.isNew was also useful in my case.

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 hash a password laravel 5.2 model create

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.

Whoops & Laravel 4.1.26

I recently upgraded to 4.1.26 on my local machine and now it seems that whoops isnt working correctly. All I am getting at the moment is a blank screen with a title as seen below, can anyone tell me why this might be happening?
http://imageshack.com/a/img841/820/tpcm.png
I can't tell what's wrong with your application until you at least enable debugging.
As a first guess though, it might be the new remember_token that was introduced in 4.1.26. A lot of people are having issues adjusting to it.
Have you updated your User model yet? If not, open:
app/models/User.php
and add the following methods:
public function getRememberToken()
{
return $this->remember_token;
}
public function setRememberToken($value)
{
$this->remember_token = $value;
}
public function getRememberTokenName()
{
return 'remember_token';
}
Then, add a new column called remember_token (of type VARCHAR(100), TEXT, or whatever equivalent you want) to your users table. It must be nullable.
Finally, when you're ready to authenticate a user, just add true as the second argument to attempt method.
if (Auth::attempt(array('email' => $email, 'password' => $password), true))
{
// At this point the user is remembered
}
That's it. Hope this solves your issue. Happy coding!
Source: Laravel Upgrade Guide

Resources