It all depends on what are the exact requirements of your project.
Gateway API usually is used to hide the complexity of microservice from external users that usually have 1 endpoint to talk to.
Also the gateway can handle the security and Authenticate the user (which many companies do indeed).
Now when you pass the gateway and your authenticated request reaches the client, usually you already have a user identity on the request (what was put onto the request by the gateway).
So you know that user "John Smith" has triggered the request.
And now if you need to call another microservice you should decide (and again its your decision):
Whether you need an authentication at all there (maybe internal communication doesn't have to be secured between microservices(
If you do need an authentication between microservices, who authenticates the request?
If its a gateway, all authentication logic is there, but you have to make an additional hop for each request that might be costy
Alternatively If its a direct call, each microservice must implement an authenticat logic. Sure, there is stuff like spring security, other languages/ecosystem have similar solutions, but in general this can be difficult to implement.
If you do make an authenticated call from microservice A to microservice B and the flow was originated by user John Smith that triggered a request to service A, you should decide whether the semantics of the call is:
- User "John Smith" contacts the service B, or...
- Service A contacts Service B on behalf of user John Smith.
This is really important for authorization if you have any kind of permissions system.
In term of technical implementation usually you can add a JWT header to the request with the required token. If the request was already authenticated and you need to generate user identity, you can merely put a couple of headers on the request.