nelsonic nelsonic - 3 months ago 45
HTTP Question

In Hapi.js can I redirect to a different endpoint and set a statusCode?

If a user is not authenticated to view a particular route (e.g:

/admin
) Auth throws a
Boom unorthorized
error I want to be able to re-direct to the
/login
but still return the
401
HTTP
statusCode
.

we have tried the following code:

const statusCode = request.output.payload.statusCode;

if(statusCode && statusCode === 401) {
return reply.redirect('/login').code(statusCode);
}


The redirect works when we remove the
.code(statusCode)
but we would ideally like to return the
401
code to the client not
302
(redirect)

Or... would it be "best practice" to return
302
...?


Context: we are developing a little (re-useable) plugin to handle errors in our Hapi App/API and one of the features is to
redirect
to
/login
when auth fails see: https://github.com/dwyl/hapi-error#redirecting-to-another-endpoint and we want to get it "right" so others can use it!

Answer

Here's the HapiJS source that's causing you grief (lib/response.js:320):

internals.Response.prototype.redirect = function (location) {

    this.statusCode = 302;
    this.location(location);
    this.temporary = this._temporary;
    this.permanent = this._permanent;
    this.rewritable = this._rewritable;
    return this;
};

As you can see, by using reply.redirect() Hapi is already replying a 302 code. You'll need to decide whether to reply with a 401 and redirect on the front end, or use the Hapi redirect and accept that it conforms to the protocol standards.

As an answer to the best practice bit, yes, Hapi is doing exactly what is expected when a server forces a redirect (302 Redirect). In order to use a 401 response, the best practice is to redirect on the client side as if you were simply navigating to the route normally.

Edit: For reference, the reply.redirect() function definition (lib/reply.js:145) is simply

return this.response('').redirect(location);

Comments