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

Expired JWT returns a 401 #3506

Open
Seluj78 opened this issue Feb 1, 2024 · 6 comments
Open

Expired JWT returns a 401 #3506

Seluj78 opened this issue Feb 1, 2024 · 6 comments
Assignees
Labels
apiv2 Planned for API v2

Comments

@Seluj78
Copy link

Seluj78 commented Feb 1, 2024

Description

When trying to use an expired token (the one I used was created on Monday and expired this morning at 9:26am GMT+1), you get a 401 response from the API.

I don't think this is standard but also it's confusing for us using the API. We cannot know if it is just because the token is expired, malformed, or missing.

I've tested with a malformed token and I get the same 401 error.

Edition

Community

Version

0.14.3-rc1

@heiytor
Copy link
Contributor

heiytor commented Feb 1, 2024

By returning 401, we inform the requester that there is an issue with the authentication, encompassing malformatted, invalid, or missing tokens. The MDN states:

The 401 Unauthorized response status code indicates that the client request has not been completed because it lacks valid authentication credentials for the requested resource.

For that reason, I don't believe there is a status code with a semantically correct meaning for each case. In my experience with API development and consumption, this behavior aligns with the standard.

However, if you have any suggestions on this matter, we would be happy to consider them.

@Seluj78
Copy link
Author

Seluj78 commented Feb 1, 2024

Thank you !

While it does make sense to only return a 401, I (personally) enforce more specifics error messages when encountering errors with authentication.

For example, taken from our main backend codebase (In Python/Flask, using flask-jwt-extended)

    @jwt.expired_token_loader
    def expired_token_loader(di, di2):  # pragma: no cover
        json = {
            "success": False,
            "error": {
                "type": "UnauthorizedError",
                "name": "Unauthorized Error",
                "message": "Token has expired.",
                "solution": "Please refresh your token.",
            },
            "code": 401,
        }
        resp = jsonify(json)
        resp.status_code = 401
        return resp

    @jwt.invalid_token_loader
    def invalid_token_loader(reason):  # pragma: no cover
        json = {
            "success": False,
            "error": {
                "type": "UnauthorizedError",
                "name": "Unauthorized Error",
                "message": f"Token is invalid: {reason}.",
                "solution": "Please refresh your token.",
            },
            "code": 401,
        }
        resp = jsonify(json)
        resp.status_code = 401
        return resp

    @jwt.needs_fresh_token_loader
    def needs_fresh_token_loader(di, di2):  # pragma: no cover
        json = {
            "success": False,
            "error": {
                "type": "UnauthorizedError",
                "name": "Unauthorized Error",
                "message": "Fresh token is needed.",
                "solution": "Please refresh your token.",
            },
            "code": 401,
        }
        resp = jsonify(json)
        resp.status_code = 401
        return resp

    @jwt.revoked_token_loader
    def revoked_token_loader(di, di2):  # pragma: no cover
        json = {
            "success": False,
            "error": {
                "type": "UnauthorizedError",
                "name": "Unauthorized Error",
                "message": "Token is revoked.",
                "solution": "Please refresh your token.",
            },
            "code": 401,
        }
        resp = jsonify(json)
        resp.status_code = 401
        return resp

    @jwt.unauthorized_loader
    def unauthorized_loader(reason):  # pragma: no cover
        json = {
            "success": False,
            "error": {
                "type": "UnauthorizedError",
                "name": "Unauthorized Error",
                "message": f"Unauthorized: {reason}.",
                "solution": "Check your parameters.",
            },
            "code": 401,
        }
        resp = jsonify(json)
        resp.status_code = 401
        return resp

    @jwt.token_verification_failed_loader
    def token_verification_failed_loader(di, di2):  # pragma: no cover
        json = {
            "success": False,
            "error": {
                "type": "UnauthorizedError",
                "name": "Unauthorized Error",
                "message": "Token verification failed.",
                "solution": "Please refresh your token.",
            },
            "code": 401,
        }
        resp = jsonify(json)
        resp.status_code = 401
        return resp

    @jwt.user_lookup_error_loader
    def user_lookup_error_loader(di, di2):  # pragma: no cover
        json = {
            "success": False,
            "error": {
                "type": "BadRequestError",
                "name": "BadRequest Error",
                "message": "User in identity not found in database.",
                "solution": "Try again.",
            },
            "code": 400,
        }
        resp = jsonify(json)
        resp.status_code = 400
        return resp

For each specific error I have a message that explains what happened and possibly how to fix it. It allows to guide developers to use our API correctly and not just get stuck with a 401 and not being sure why

@heiytor
Copy link
Contributor

heiytor commented Feb 1, 2024

Unfortunately, the current state of the API lacks descriptive error messages. Addressing this is a key goal for the upcoming v2 version.

I plan to keep this issue open and will add a milestone, closing it upon the release of v2. Sound good to you?

@heiytor heiytor self-assigned this Feb 1, 2024
@heiytor heiytor added the apiv2 Planned for API v2 label Feb 1, 2024
@Seluj78
Copy link
Author

Seluj78 commented Feb 1, 2024

Wonderful, sounds great to me! Thank you very much for taking this into consideration

@Seluj78
Copy link
Author

Seluj78 commented Feb 1, 2024

Quick question, when can we expect the api V2 to enter into development/be released ?

@heiytor
Copy link
Contributor

heiytor commented Feb 2, 2024

Quick question, when can we expect the api V2 to enter into development/be released ?

Currently, we're finalizing the requirements, so I cannot provide a specific date for the start of development.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
apiv2 Planned for API v2
Projects
None yet
Development

No branches or pull requests

2 participants