wp-graphql / wp-graphql-jwt-authentication

Authentication for WPGraphQL using JWT (JSON Web Tokens)
GNU General Public License v3.0
341 stars 74 forks source link

expired token problem #95

Open vana-dev opened 4 years ago

vana-dev commented 4 years ago

Hi, refreshing jwt token is something new for me. I have some issue, my app is based on vue and nuxt.js, to connecting to wp graphql I use apollo module. Token expiring time is very short, and when it expire I got globally error on entire app: NuxtServerError GraphQL error: Internal server error. How to prevent this error if token is expired or invalid, and how to handle auto refreshing token?

THPubs commented 4 years ago

I'm also facing the same problem here. If the token is expired, the error message read as Internal server error. If we can have a meaningful error message saying Token expired, we can catch that and send the call to refresh the token.

vana-dev commented 4 years ago

I figure out how to avoid this kind of error, you have to set expiration date on apollo token cookie same as jwt token expiration on the server side.

Next thing to do is auto refreshing function. I try to make it work in vuex store on nuxtServerInit. I save jwtRefreshToken in another cookie, but build in function in apollo module $apolloHelpers.onLogin() doesn't work, it not update the new refreshed token and authorization data on client side.

THPubs commented 4 years ago

But I think the right way is to return a 403 error code from the server right?

jonshipman commented 4 years ago

Another point, a failed authorization shouldn't break public data. E.g. only the queries that require authorizations should fail.

huniqcast commented 4 years ago

The problem with this comes from the graphql-php plugin used internally by wp-graphql as it replaces the meaningful message set by this plugin when token is invalid by a generic message Internal server error for the security reason.

The Exception class used by this plugin set with this action :

add_action( 'graphql_before_resolve_field', function() use ( $token ) {
  throw new \Exception( $token->get_error_code() . ' | ' . $token->get_error_message() );
}, 1 );

needs to implements the GraphQL\Error\ClientAware for the invalid-jwt | xxxx to remains unchanged as explain in this link

@jasonbahl we need your help to properly implement this.

huniqcast commented 4 years ago

I can confirm when I replace the generic \Exception PHP class with \GraphQL\Error\UserError class exception the message from the invalid token is displayed on the client-side.

felipepxavier commented 4 years ago

Activating the "debug" mode we receive the message "" invalid-jwt | The iss do not match with this server "", any other alternatives?

jasonbahl commented 4 years ago

@felipepxavier based on that error, it seems like you're maybe using a token issued from another server.

Are you trying to get a token from a local or staging server and trying to use it on production or something like that?

Can you provide more information on what you're doing to get to this point?

matepaiva commented 3 years ago

Any news about this? I receive an internal server error when the token is expired. Shouldn't it return a 403 error or something like that?

victors1681 commented 3 years ago

The same issue with the same origin URL, if we at least can get UNAUTHENTICATED will be easier to refresh the token.

topheroes commented 3 years ago

I can confirm when I replace the generic \Exception PHP class with \GraphQL\Error\UserError class exception the message from the invalid token is displayed on the client-side.

@huniqcast Could you please share your code?

@vana-dev Did you solve the problem? Could you please comment on it?

victors1681 commented 3 years ago

@topheroes go to: wordpress/wp-content/plugins/wp-graphql-jwt-authentication-develop/wp-graphql-jwt-authentication.php line 192 start like this add_action( 'init_graphql_request', function() {

change:

throw new \Exception( $token->get_error_code() . ' | ' . $token->get_error_message() );

to

throw new \GraphQL\Error\UserError( __( $token->get_error_message(), 'wp-graphql-jwt-authentication' ) );

you will get something like this

{
    "errors": [
        {
            "message": "Expired token",
            "extensions": {
                "category": "user"
            },
            "locations": [
                {
                    "line": 2,
                    "column": 5
                }
            ],
            "path": [
                "customer"
            ]
        }
    ],
    "data": {
        "customer": null
    },
    "extensions": {
        "debug": []
    }
}

Additionally, I created a new Error Called AuthError and I changed the category to say auth because I'm using Apollo and I need to identify when I have a user error or auth error.

 "message": "Expired token",
            "extensions": {
                "category": "auth" <-----
            },
topheroes commented 3 years ago

@victors1681

Thank you for your reply. I'm getting Status: 200 OK

And reply

{
    "errors": [
        {
            "message": "The iss do not match with this server",
            "extensions": {
                "category": "user"
            },
            "locations": [
                {
                    "line": 2,
                    "column": 3
                }
            ],
            "path": [
                "addToCart"
            ]
        }
    ],
    "data": {
        "addToCart": null
    },
    "extensions": {
        "debug": []
    }
}

Should I rely on the error text to request a new token? What's the best practice here? I was expecting a specific status or error code to handle, so I'm a little bit confused about it.

The error text is "The iss do not match with this server" no matter if

define( 'WP_DEBUG', true );
define( 'GRAPHQL_DEBUG', true );

defined or not. @felipepxavier did you solve the problem?

Thank you in advance!

nonlinearcom commented 3 years ago

Hi, I'm facing the same issue, is there any update or workaround for it?

Parkerhiphop commented 3 weeks ago

If anyone is still struggling with The iss does not match with this server.

You can try graphql_jwt_auth_iss_allowed_domains to migrate to a new domain or extend the ISS.

add_filter('graphql_jwt_auth_iss_allowed_domains', function($allowed_domains) {
    return array_merge($allowed_domains, [
       'https://example.com',
       'https://example-2.com'
    ]);
});

I found this solution within the source code: https://github.com/wp-graphql/wp-graphql-jwt-authentication/blob/5d202620ef1989bb94ebe57161b2a58591327b6c/src/Auth.php#L610-L628