We do these things with the gateway:

  • 1. Implement the routing function.
  • 2. Integrate Swagger API documentation;
  • 3. Modify the URI globally.
  • 4. Verify the Token.
  • 5. Verify resource access permissions.
  • 6. Open API unified signature verification.

Implementing the Routing function

The purpose of the routing function is to unify the traffic inlet and shield the existence of multiple microservices on the back end for the front end, without exposing interfaces to the Internet through domain names for each microservice on the back end.

Before our project is through nginx request routing function, but we need not only routing function, routing function is only the most basic function of the gateway.

Integrate Swagger API documentation

After the microservization of the project, interface documents were dispersed. In the early stage, since we used Nginx for routing, it was too troublesome to configure Swagger routing, and front-end colleagues also needed to remember routing rules, we gave up accessing interface documents by configuring routing.

Before there was no gateway, front-end colleagues could not access the interface documents of the test environment. We had to start microservices locally to allow front-end colleagues to access THE API interface documents through the LAN.

With the introduction of the gateway we hope to unify the API document entry. The author has separately compiled a tutorial entitled “Detailed Steps to Merge Multiple Microservice Swagger Interface documents in the Gateway”, and the final effect is shown in the figure below.

Global modification of the file URI

Since domain names and route prefixes are subject to modification, we usually only store the relative path of the picture to the database after uploading the picture, but the response to the front end must be a complete URL, otherwise the picture cannot be accessed. Therefore, we must join the domain name and route for all picture URLS before responding.

For example, to modify the user profile picture, the front end needs to invoke the file upload interface to upload the image and obtain the URL of the uploaded image, and then invoke the interface to modify the user profile picture with the URL of the image. As the front-end may need to implement echo after upload, the picture URL responding to the file upload interface must also be complete. As a result, the picture URL transmitted by the front-end call to modify the user profile picture interface is also complete, so we have to remove the domain name and route of the profile picture URL in the interface for modifying the user profile picture.

One interface can do that. How many interfaces? If you take the trouble, you can write this for every interface.

For this kind of repetitive operation, we choose to move it to the unified implementation of the gateway, and other micro-services do not need to make any changes after the routing and domain name are modified.

It is not difficult to remove or concatenate the domain name and route for the image URL. It is difficult to identify which fields are the file URL from the request body and from the response body.

The first is how to identify which field is passed the file URL from the request body. Because the url of the file passed by the front end is complete, regular match can be used to replace the url according to the domain name, route, and filename suffix. Domain name, route, and file name suffix are all indispensable. Matching domain names and routes is to avoid matching image links to third-party websites or previously uploaded images (backward compatibility), and matching filename suffixes is to ensure that this is a file link, not an interface link.

The second is how to identify from the response body which field is passing the file link. We can only match by the suffix name. After matching the suffix name, we also need to judge whether the link is already a complete link. For complete links, there is no need to do splicing.

A note of caution during implementation: When we modify the request or response body, its length may change, so we must remember to change the ContentLength of the request or response header.

If the Gateway is based on the Spring Cloud Gateway implementation, since it is asynchronous and responsive, the request header is written to the InputStream stream and then to the body, instead of being written together. So it makes no sense to modify the ContentLength of the request header after we modify the body. In cases where the length of the modified body is not known, the solution could be to remove the ContentLength of the request header and replace it with transfer-Encoding: chunked.

Verify the limitation of tokens

When nginx is still used for request forwarding, each microservice needs to write a set of token verification logic, such as the interception to verify whether the request carries the token and whether the token is valid. To obtain user information, it is necessary to obtain token from request header first, and then check Redis to obtain user identity information.

After the gateway is introduced, we only need to do token verification on the gateway. After the verification is passed, the user information is obtained from Redis and written to the request header. At the same time, the token is removed from the request header. The userId is passed by the gateway to the backend micro service, which does not need to obtain the userId again based on the Token.

Verify resource access permissions in a unified manner

After the introduction of the gateway, except for the login (Token) verification, the verification of users’ access to resources can be implemented on the gateway, and each micro-service does not care about the verification of permission.

The user center is still responsible for verifying user resource access permissions. The gateway only invokes the permission verification interface provided by the user center to verify user resource access permissions. This may affect the performance of the interface. Try to make the user center fully read the data source cache when implementing the interface for permission verification.

Open API unified signature verification

Our open API uses signature-based mechanism to implement identity authentication, which can control the limited time of signature. I’ve written about signature mechanisms before: “A Simple and secure API Authorization Mechanism Based on a signature algorithm.”

Prior to the introduction of gateways, we implemented it via AOP and just needed to add an annotation on the open API method. The key, private key, and signature validity period are specified in the configuration file. After the gateway is introduced, the signature verification can be implemented uniformly on the gateway.

If the API needs to be provided to multiple principals, that is, to be used by multiple cooperative customers, the configuration function of keys and keys must be provided in the background, and the configuration is persisted to the database. The gateway also needs to support key query and signature verification. The gateway can cache key and key dictionaries in the memory and refresh them periodically. Or cache to Redis and refresh the cache synchronously when the key of the account is updated.

conclusion

The gateway is generally used for unified traffic entry, authentication, and traffic control. In addition, some redundant operations unrelated to services can be implemented on the gateway. For example, the unified SwaggerAPI document entry introduced in this section automatically removes or concatenates domain names and routes for file urls. Internal and external interfaces can also use the gateway to perform signature verification and access frequency restriction.