phprestcakephpandroid-webservicephp-password-hash

How to request for login with email and plain text password in cakephp3


I am new in php and working on REST API in cakephp3 for my android application.

after setting up php and composer and routing I created login function..

public function login() {
    $this->request->allowMethod('post');
    $this->loadModel('Users');
    $entity = $this->Users->newEntity($this->request->data, ['validate' => 'LoginApi']);
    if ($entity->errors()) {
        $this->httpStatusCode = 400;
        $this->apiResponse['message'] = 'Validation failed.';
        foreach ($entity->errors() as $field => $validationMessage) {
            $this->apiResponse['error'][$field] = $validationMessage[key($validationMessage)];
        }
    } else {
        $hasher = new DefaultPasswordHasher();
        $password = $hasher->hash($entity->password);

        $user = $this->Users->find()
            ->where([
                'email' => $entity->email,
                'password' => $password
            ])
            ->first();
        if (empty($user)) {
            $this->httpStatusCode = 403;
            $this->apiResponse['error'] = 'Invalid email or password.';
            return;
        }
        $payload = ['email' => $user->email, 'name' => $user->name];
        $this->apiResponse['token'] = JwtToken::generateToken($payload);
        $this->apiResponse['message'] = 'Logged in successfully.';
        isset($user);
        isset($payload);
    }
 }

I use 123456 for password and this hasher returns random string every time, but the password which is already saved in database for 123456 is $2y$10$f7K02jamD7ZeGHLcTkP6Weh6VsthMWHiwqHJmcqbsxuLCKGCQCGCu this.

that is why it gives Invalid password in response.

My question is how to match the exact same string or hashing for request. thanks in advance.


Solution

  • With reference to this answer

    Use this line

    password_verify($entity->password, $user->password)
    

    instead of this

    $hasher = new DefaultPasswordHasher();
    $password = $hasher->hash($entity->password);
    

    you can try this function

    public function login()
    {
        $this->request->allowMethod('post');
        $this->loadModel('Users');
        $entity = $this->Users->newEntity($this->request->data, ['validate' => 'LoginApi']);
        if ($entity->errors()) {
            $this->httpStatusCode = 400;
            $this->apiResponse['message'] = 'Validation failed.';
            foreach ($entity->errors() as $field => $validationMessage) {
                $this->apiResponse['error'][$field] = $validationMessage[key($validationMessage)];
            }
        } else {
            $user = $this->Users->find()->where(['email' => $entity->email])->first();
            if (count($user)) {
                if (password_verify($entity->password, $user->password)) {
                    $payload = ['email' => $user->email, 'password' => $user->password];
                    $this->apiResponse['token'] = JwtToken::generateToken($payload);
                    unset($user->password);
                    $this->apiResponse['response'] = array($user);
                    unset($user);
                    unset($payload);
                } else {
                    $this->httpStatusCode = 403;
                    $this->apiResponse['error'] = 'Incorrect password';
                    return;
                }
            } else {
                $this->httpStatusCode = 403;
                $this->apiResponse['error'] = 'Email not found';
                return;
            }
        }
    }