Search code examples
javascriptnode.jshttphttp-status-codeshapi.js

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!


Solution

  • 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.

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

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

    EDIT Dec '16: Kelly Milligan below pointed out that using reply.redirect().code() is now supported by HapiJS and won't send a 302 status if you don't want it to.