spiral / app

Spiral Framework Skeleton HTTP Application: Queue, Console, Cycle ORM
https://spiral.dev/
MIT License
191 stars 20 forks source link

Can't access authorized user after login #21

Closed sujit-baniya closed 4 years ago

sujit-baniya commented 4 years ago

I've set

// Session
Framework\Auth\TokenStorage\SessionTokensBootloader::class,
// Database Session Storage
Framework\Auth\TokenStorage\CycleTokensBootloader::class,

And I could login with following code LoginController.php:

public function loginPost(LoginRequest $login)
    {
        if (!$login->isValid()) {
            return [
                'status' => 400,
                'errors' => $login->getErrors()
            ];
        }

        // application specific login logic
        $user = $this->users->findOne(['username' => $login->getField('username')]);
        if (
            $user === null
            || !password_verify($login->getField('password'), $user->password)
        ) {
            return [
                'status' => 400,
                'error'  => 'No such user'
            ];
        }

        // create token
        $token = $this->authTokens->create(['userID' => $user->id]);
        $this->auth->start(
            $token
        );

        return [
            'status'  => 200,
            'message' => 'Authenticated!',
            'token' => $token
        ];
    }

But When I tried to access protected route, home HomeController.php, I'm not getting the details of authorized user

 public function index(): string
    {
        if ($this->auth->getActor() === null) {
            throw new ForbiddenException();
        }

        dump($this->auth->getActor());
    }

Here, I'm getting Forbidden. I'm following as per this documentation: https://spiral.dev/docs/security-authentication#actor-provider-and-token-payload

Here the browser testin : https://storyxpress.co/video/k8wzh5q7nz2rsgwv3

home/index: https://github.com/itsursujit/go-php/blob/master/app/src/Controller/HomeController.php#L43 Am I doing something wrong?

[UPDATED: $this->auth on Controller returning null]

sujit-baniya commented 4 years ago

Not even working with

public function loginPost(LoginRequest $login)
   {
       if (!$login->isValid()) {
           return [
               'status' => 400,
               'errors' => $login->getErrors()
           ];
       }

       // application specific login logic
       $user = $this->users->findOne(['username' => $login->getField('username')]);
       if (
           $user === null
           || !password_verify($login->getField('password'), $user->password)
       ) {
           return [
               'status' => 400,
               'error'  => 'No such user'
           ];
       }

       // create token
       $token = $this->authTokens->create(['userID' => $user->id]);
       $this->auth->start(
           $token
       );

       if ($this->auth->getActor() === null) {
            throw new ForbiddenException();
        }

        dump($this->auth->getActor());
   }
wolfy-j commented 4 years ago

Have you tried accessing Actor in a new request after that? Do you have ActorProviderInterface connected to your ORM entity?

https://spiral.dev/docs/security-authentication#actor-provider-and-token-payload

sujit-baniya commented 4 years ago

Yes, I did try accessing Actor, Please check this file: https://github.com/itsursujit/go-php/blob/master/app/src/Database/User.php

ActorProviderInterface Connted to ORM entity: https://github.com/itsursujit/go-php/blob/master/app/src/Repository/UserRepository.php

Still can't access authenticated user: https://github.com/itsursujit/go-php/blob/master/app/src/Controller/HomeController.php#L43

sujit-baniya commented 4 years ago

Also Please check this video: https://storyxpress.co/video/k8x5q34nms4w3a0ke

wolfy-j commented 4 years ago

You did not connect UserBootloader so no user can be located. I'll make the error more obvious in the next release.

sujit-baniya commented 4 years ago

How would I connect UserBootloader?

wolfy-j commented 4 years ago

See the PR I sent you, add it to App, same as FakerBootloader

wolfy-j commented 4 years ago

https://github.com/itsursujit/go-php/pull/1/commits/62f08fe09c104391e9eff3601a16047b058378fd

sujit-baniya commented 4 years ago

I merged it. Still can't make it work https://github.com/itsursujit/go-php/blob/master/app/src/Controller/HomeController.php#L43 Still getting: Invalid Login Attempt or user not found

sujit-baniya commented 4 years ago

https://storyxpress.co/video/k8x6u0vf6glgyh7iv

sujit-baniya commented 4 years ago

@wolfy-j Anything I'm missing here?

wolfy-j commented 4 years ago

Sorry, I can't check at the moment (work). Will take a look closer to the evening.

Make sure to activate HttpAuth and check if the value of the cookie was set. https://spiral.dev/docs/security-authentication#installation-and-configuration

sujit-baniya commented 4 years ago

I'd applied everything mentioned in the link above

wolfy-j commented 4 years ago

Can you check if the cookie was set?

sujit-baniya commented 4 years ago

Cookies are not set

sujit-baniya commented 4 years ago

Have only:

array(2)
[
·    ['csrf-token'] = string(16) bGeBK+Jl0sBJKSWD
·    ['sid'] = string(26) bu0jf4n1cmmt1k1v74v982tatl
]
wolfy-j commented 4 years ago

The cookie token must be set after the successfull authentication. If it wasn't I'd have to check your build again. It is def working on production for us so it seems like some misconfiguration.

sujit-baniya commented 4 years ago

I checked again: https://www.loom.com/share/3a7304c0b34b4e7ebf9d013f4894b13d

No such cookies storing... Any suggestions I should be looking into?

sujit-baniya commented 4 years ago

@wolfy-j Probably the cookies is not accessible via other controller or browser. This is because.

I did dump($this->cookies->getAll() and I could see token right after validating login data

public function loginPost(LoginRequest $login)
    {
        $this->session->getSection('auth')->clear();
        if (!$login->isValid()) {
            return [
                'status' => 400,
                'errors' => $login->getErrors()
            ];
        }

        // application specific login logic
        $user = $this->users->findOne(['username' => $login->getField('username')]);
        if (
            $user === null
            || !password_verify($login->getField('password'), $user->password)
        ) {
            $uri = $this->router->uri('login', [
                'error' => 'Invalid Users'
            ]);
            return $this->response->redirect($uri);
        }

        // create token
        $this->auth->start(
            $this->authTokens->create(['userID' => $user->id])
        );
        // dump($this->cookies->getAll());
        $this->session->getSection('auth')->set('token', $this->auth->getToken());
        return $this->response->redirect($this->router->getRoute('home')->uri());
    }

Any suggestions after above finding?