A hacker can't and won't modify the token. As the token itself is safe and is fully trusted. This is the nature of a JWT. So without additional information you can't tell the difference.
You can however design a strategy to protect your resource.
Most important is to prevent a hacker from 'stealing' the token. It helps when you send the token always over a secured line and store information (like tokens) in a secured place.
Make it not worthwhile to hack the token. Use short-lived tokens, like five minutes or less. When a hacker gets hold of a token it will only give access for a short period. This is the 'acceptable loss'. On the other hand the hacker is discouraged as the effort is not worth the result.
Detect suspicious behaviour. Like hundred hits per second or varying ip addresses with the same token.
When using a refresh token, check the requesting party. Is the Ip address within range? Use one-time only refresh tokens. Only allow refresh tokens when the client can keep a secret. Use expiration on refresh tokens, this will force the user to login every now and then.
And add additional information to the claims in the token. Like the ip address, used agent, etc. These are quick checks.
When the ip address is not the same as in the claim, do not accept the token. The app will need to send a refresh token to obtain a new access token. The hacker can't do this without a refresh token.
Keep track of succesful login ip addresses. For a known ip address the token can be refreshed. For an unkown ip address (a possible hacker, or unknown changed wifi network), invalidate the refresh token. That way the user is forced to login again.
As an additional security measure contact the user (send an e-mail like Google does) when there was something different. In that case the user can revoke the refresh token.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…