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