_ reproduced from: https://mp.weixin.qq.com/s/6Wsbn8kPiF8lD4PmXEn8sw_

In daily development, there are always interfaces to work with. Front-end and back-end data transmission interfaces and third-party service platform interfaces. The data transmission interfaces at the front and back ends of a platform generally communicate in the Intranet environment and use a security framework, so the security is well protected. This article focuses on how to design business interfaces for third-party platforms. What questions should we consider?

Mainly from the above three aspects to design a safe API interface.

1. Security Issues

Security is a specification that interfaces must guarantee. If an interface is not secure, your interface is exposed to the public network.

1.1 Prerequisite for calling the interface – Token

Obtaining a token usually involves several parameters’ appID ‘, ‘appkey’, ‘timestamp’, ‘nonce’, ‘sign’. We use the above parameters to get the credentials to call the system.
‘AppID’ and ‘AppKey’ can be directly applied online through the platform, or directly issued offline. ‘AppID’ is globally unique, each ‘appID’ will correspond to a customer, ‘appkey’ needs to be highly confidential.
‘timestamp’ is a timestamp, using the system’s current Unix timestamp. The purpose of timestamps is to mitigate DOS attacks. Prevents attempts to request the interface after a request has been intercepted. The server side sets the timestamp threshold, and if the request timestamp and server time exceed the threshold, the response fails.
‘nonce’ is a random value. The random value is mainly used to increase the variability of ‘sign’ and also to protect the idempotency of the interface. The nonce of two adjacent requests is not allowed to repeat. If repeated, it is considered as repeated submission and the response fails.
‘sign’ is a parameter signature that combines’ appkey ‘, ‘timestamp’ and ‘nonce’ for MD5 encryption (of course irreversible encryption using other methods is also ok).
‘token’, using arguments’ appID ‘, ‘timestamp’, ‘nonce’, ‘sign’ to obtain the token as the unique credential of the system call. ‘Tokens’ can be set to be valid once (for greater security) or to be time-limited, which is recommended. The frequency of requests to this interface may be high if it is valid once. The ‘token’ is recommended to be added to the request head so that it can be completely separated from the business parameters.

1.2 Using POST as the interface request mode

The two most common ways to invoke interfaces in general are GET and POST. The difference is also obvious, as GET requests expose parameters in the browser URL and have a limit on length. For higher security, all interfaces request through POST.

1.3 Client IP Address Whitelist

The IP address whitelist allows the access permission of an interface to some IP addresses. In this way, other IP addresses can be used to prevent access attacks. The tricky part of setting an IP address whitelist is that after the client is migrated, you need to contact the service provider to add a new IP address whitelist. There are many ways to set IP whitelists. In addition to traditional firewalls, Sentinel, a component provided by Spring Cloud Alibaba, also supports whitelisting Settings. To reduce API complexity, you are advised to use firewall rules to set whitelists.

1.4 Traffic Limiting for a Single Interface

Current limiting is to better maintain system stability. Redis is used to count the number of interface calls, with IP + interface address as key, access times as value, and value+1 for each request. The expiration period is set to limit the call frequency of the interface.

1.5 Recording Interface Request Logs

Use AOP global request log, quickly locate abnormal request location, troubleshoot the cause of the problem.

1.6 Desensitization of sensitive data

In the process of interface invocation, sensitive data such as order number may be involved. Such data usually needs desensitization, and encryption is the most commonly used method. The encryption mode is RSA asymmetric encryption with high security. Asymmetric encryption algorithms have two keys that are completely different but exactly match. Only a matching pair of public and private keys can be used to encrypt and decrypt plaintext.

Bismidempotent problem

Idempotent means that the execution result of any number of requests has the same effect as the execution result of a single request. To put it bluntly, the query operation does not affect the data itself no matter how many times it is queried, so the query operation itself is idempotent. But the database changes every time a new operation is performed, so it’s nonidempotent.
There are many ways to solve idempotent problems, and here is a more rigorous one. Provides an interface for generating random numbers, which are globally unique. Call the interface with a random number. When the service is successfully processed for the first time, the random number is used as the key, the operation result is used as the value, and the redis is saved. At the same time, the expiration time is set. The second call, which queries redis, returns an error if the key is present.

Data specification problem

3.1 Version Control

A mature set of API documentation, once published, does not allow arbitrary modification of the interface. If you want to add or modify an interface, you need to add version control. The version number can be an integer or a floating-point number. Generally, the interface address contains the version number, http://ip:port//v1/list.

3.2 Response status code specification

A great API, but also to provide a simple response value, based on the status code to roughly know what the problem is. We use the HTTP status code for data encapsulation, for example, 200 indicates that the request is successful, 4xx indicates that the client error, 5xx indicates that the server internal error. The status code design reference is as follows:
classification describe
1xx Message, the server receives the request and requires the requester to proceed with the operation
2xx successful
3xx Redirect, requiring further action to complete the request
4xx Client error, request contains syntax error or request cannot be completed
5xx Server error

Status code enumeration class:

Public enum CodeEnum {// Add SUCCESS(200," processing succeeded "), ERROR_PATH(404," request address error "), ERROR_SERVER(505," server internal error "); private int code; private String message; CodeEnum(int code, String message) { this.code = code; this.message = message; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; }}Copy the code

3.3 Unified response data format

In order to facilitate the response to the client, the response data will contain three attributes: status code, message description and response data. The client can quickly know the interface based on the status code and information description. If the status code is returned successfully, the client can process data again.

Definition of response results and common methods:

public class R implements Serializable { private static final long serialVersionUID = 793034041048451317L; private int code; private String message; private Object data = null; public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public Object getData() { return data; } /** * public R fillCode(CodeEnum CodeEnum){this.setCode(CodeEnum CodeEnum); this.setMessage(codeEnum.getMessage()); return this; } public R fillCode(int code, String message){this.setCode(code); this.setMessage(message); return this; } public R fillData(Object data) {this.setCode(CodeEnum.success.getCode ()); this.setMessage(CodeEnum.SUCCESS.getMessage()); this.data = data; return this; }}Copy the code

conclusion

This article discusses API design specifications in terms of security, idempotency, and data specifications. In addition, a good API also requires good interface documentation. The readability of interface documentation is very important, even though many programmers don’t like to document and don’t like people to document. In order not to increase programmer pressure, it is recommended to use Swagger or other interface management tools. With simple configuration, interface connectivity can be tested during development and offline documents can be generated for API management.