rack-jwt
rack-jwt copied to clipboard
Customize error messages from Auth
reported by @Morred
https://github.com/eigenbart/rack-jwt/issues/9
Hi there,
First of all, thanks for writing this gem, it's super useful!
I guess this one is more like a feature request, I'm looking for a way to customize the format of the error responses of the Auth class.
Every time something fails, it will automatically return a 401 response with the error body format that is hardcoded into this method, so currently I'm just monkeypatching the return_error method to build the error body into the format I need.
Is a general, more flexible way to format the error responses something you would consider adding to this gem?
I know, it is obvious, but i think that good way to handle it is add localization files, just like in other gems like device. It is easy to develop, needs one default english-locale file somewhere inside the gem (no need to do generator for that). Also need to have configurable path to user locale file for overlapping and default value for it, or several, if it needs to do for distinct frameworks.
@xfynx honestly I don't think localization is needed here. Error messages returned by the gem are not meant to be shown to the user, they are useful for logging and debugging but the client should show "Authentication failed" instead of "Invalid JWT token : Signature Verification Error", wdyt?
@morred what's the point of having custom error messages? do you need a different format than {error: message}
to accommodate error messages to your client without changes maybe?
@eparreno yeah, you are right, there is no need more dependencies for gems like this. and "Authentication failed" is a great variant. In general i think that current variant is okay: no exceptions, that will return something another than 401 with description. From another point of view if it will be used as it is, it needs more common messages for user, but not scary "Invalid JWT ID" or "Incorrect Key Algorithm"
I'd like to be able to do more than customize the error message string. I'd like to return a JSON error message with the same structure as all my other API errors. I haven't yet settled on exactly what that structure will be (I'm studying this SO answer). I was hoping I could pass a block as one of the options to customize the error generation.
@eparreno do you mind sharing your monkey patch?
@eparreno Yeah I had to work against a spec that expected a very specific error response format.
@mpoisot I patched it like this:
require 'jwt'
module Rack
module JWT
class Auth
def return_error(message)
body =
{
errors: {
code: '401',
title: 'Authentication failure',
details: message
}
}.to_json
headers = { 'Content-Type' => 'application/json', 'Content-Length' => body.bytesize.to_s }
[401, headers, [body]]
end
end
end
end
Now that just hardcodes the exact error message that I needed, but it shouldn't be too hard to change it so it accepts a custom error message template. I can give it a go if that's something you guys would be interested in adding to the gem.
I ended up here also looking for a way to customise the HTTP 401 JSON. How about an option, say, called customize_unauthorized_response
, which is a proc
that accepts the original message
?
The default proc
would emulate the current behavior:
CUSTOMIZE_UNAUTHORIZED_RESPONSE = Proc.new { |message| { error: message } }
Then, return_error
would just call either a provided proc, or, the default if none provided, to format the body:
def initialize(app, opts = {})
@app = app
@customize_unauthorized_response = opts.fetch(:customize_unauthorized_response, CUSTOMIZE_UNAUTHORIZED_RESPONSE)
....
def return_error(message)
body = @customize_unauthorized_response.call(message).to_json
...
Is that too much indirection? Thoughts? I could try a PR if there is interest in this feature.
All this being said, I'm just looking to dupe the HTTP status code in the body because I'm dealing with a client that has no access to the HTTP status (!).
Whoops, I just noticed @mpoisot suggested passing in a block as well. Apologies for the dupe.
Sorry for the delay guys, gonna check that one today since a few people is interested
@eparreno any updates? At least 1 day passed :P