Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

request.auth.credentials undefined after calling request.auth.session.set #48

Closed
Zambonilli opened this issue Jan 3, 2015 · 10 comments
Closed
Assignees
Labels
support Questions, discussions, and general support

Comments

@Zambonilli
Copy link

I think this is more of a question than an issue. In my login page I'd like to perform the login, set the credentials and then display the user's authenticated dashboard without redirecting to the dashboard url. It looks like when I call reply.view with the request.auth.credentials after calling request.auth.session.set it is undefined. Is this because the credentials are set earlier in the pipeline and calling set doesn't update until the next request?

IE:
// do login stuff and get a user object that we want to save in session
request.auth.session.set(user);

reply.view('dashboard', { user: request.auth.credentials });

@jaw187
Copy link
Contributor

jaw187 commented Jan 4, 2015

This is because request.auth.session.set is used for setting the cookie object. request.auth.credentials is only set after a request is successfully validated against an auth scheme. In the case of your route, the request is unsuccessfully authenticated, your validation logic is executed, and the cookie is set. But request.auth.credentials was already set to null and request.auth.session.set isn't going to update it.

The most straight forward approach would be to separate your dashboard and login logic, then use reply with reply.redirect('/dashboard') upon successful user validation.

However, you can use the onPreAuth extension point in the request life cycle to do things differently if you'd like. http://hapijs.com/api#request-lifecycle

@jaw187 jaw187 closed this as completed Jan 4, 2015
@jaw187 jaw187 added the question label Jan 4, 2015
@jaw187 jaw187 self-assigned this Jan 4, 2015
@Zambonilli
Copy link
Author

Thanks for the quick response. This is what I figured was happening. I'll just take the performance hit of the reply.redirect because it's more pragmatic.

@technowar
Copy link

I am using XMLHttpRequest. How should I separate my login logic, and use reply.redirect?

When I add reply.redirect('/home'), an error will appear on my browser(Chrome) stating -- XMLHttpRequest cannot load server/login. The request was redirected to 'server/home', which is disallowed for cross-origin requests that require preflight. even though I have enabled cors.

@Zambonilli
Copy link
Author

I would just handle the redirect to /home client side in javascript if you're doing an ajax call. It seems a little cleaner that way too if you're using ajax for navigation logic. My guess is that the browsers have weird behavior with following a redirect from an ajax request.

@technowar
Copy link

So if I have this on my route,

{
    method: 'POST',
    path: '/login',
    config: {
        handler: function (request, reply) {
            User.find({
                'email' : request.payload.email,
                'password' : request.payload.password,
            }, function (error, data) {
                if (!data.length) {
                    throw new Error(error);
                }
                request.auth.session.set(data[0]);
                return reply(data[0]);
            });
        },
        auth: {
            mode: 'try',
            strategy: 'session'
        },
        plugins: {
            'hapi-auth-cookie': {
                redirectTo: false
            }
        }
    }
}

and this on my XMLHttpRequest,

var xhrContent = '{\
    "email" : "' + email + '",\
    "password" : "' + password + '"\
}';

xhr.open('POST', 'server/login');
xhr.onload = function () {
    var responseMessage = JSON.parse(this.responseText);
    if (responseMessage.error) {
        return responseMessage.message;
    }
}
xhr.send(xhrContent);

Where should I put my redirect? I tried to add console.log(request.auth.credentials) right after setting the session and returns null. However, on my browser (Chrome) under Network tab and Headers tab, it has set-cookie and some random value. And under Preview tab, it contains data of the user I tried to login.

@jaw187
Copy link
Contributor

jaw187 commented Feb 7, 2015

You won't be able to use a redirect. If you're concerned about requesting protected resources via an ajax requests, you'll need to handle errors to trigger the logic to get user/pass within your own client app.

request.auth.credentials will be available on all subsequent requests, but not immediately after setting the session.

The browser is handling the ajax request as expected. The random value is the encrypted cookie which will be used on your future requests.

@technowar
Copy link

@jaw187, am I doing this the right way?

@jaw187
Copy link
Contributor

jaw187 commented Feb 7, 2015

The redirect is disabled correctly. Your handler needs to be able to reply with an error. This is how I'd write your handler and I'd use Boom (https://github.com/hapijs/boom)...

            }, function (error, data) {

                if (error) {
                    return reply(Boom.wrap(error));
                }

                if (data && data.length) {
                    request.auth.session.set(data[0]);
                    return reply(data[0]);
                }

                return reply(Boom.unauthorized());
            });

From that point on it all depends on the implementation of your client app.

@technowar
Copy link

@jaw187, thank you. And sorry @Zambonilli for trying to hijack your issue.

@Marsup Marsup added support Questions, discussions, and general support and removed question labels Sep 21, 2019
@lock
Copy link

lock bot commented Jan 9, 2020

This thread has been automatically locked due to inactivity. Please open a new issue for related bugs or questions following the new issue template instructions.

@lock lock bot locked as resolved and limited conversation to collaborators Jan 9, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
support Questions, discussions, and general support
Projects
None yet
Development

No branches or pull requests

4 participants