The identifier in the URL can be always faked by an attacker. You need a mechanism to ensure that the identifier is actually valid. This is why when modelling endpoints executing a certain operation, the url value is not considered a granting authority and instead a different mechanism is implemented (sessions, JWT tokens,...). And then if you decide you don't trust the URL value anyway, for certain endpoints it's probably the best to drop the value altogether.
With that in mind, in your case you should always extract the user identification from the JWT token and perform role-based authorisation on the identity from the token. Thanks to secret sharing of encryption keys, once you do validate the JWT token on the backend, you are pretty much guaranteed it hasn't been forged and therefore the value of the identity is to be trusted. Now, whether the user whose identity is trusted based on the header value actually has valid permissions to access a certain resource, that's up to business requirements and needs to be modelled separately.
But what if an attacker steals the JWT access token?
To prevent this, issue short-lived access token (in terms of minutes), which can be refreshed with a (long-lived) refresh token. If an attacker steals an access token, they won't be able to do that much harm, if their token remains active only for a short period of time and then expires.
Which approach to ultimately take?
It depends on the use case.
I can imagine, for administration endpoints (on which system administrators operate), you could expose an endpoint accepting a user identification in the URL, but this endpoint would only be available for users with e.g. users:admin role. Not many users would have this role and that would be your way to protect an endpoint where a user A can change information of other users.
For "regular" users, you could have a completely different endpoint, which could e.g. contain the word /self/ in its structure, wouldn't accept an identifier and would act on a user based on the JWT token.