Front-end implementation of request signature
The front-end encrypts the request parameters as signature.
1. Ideas
General request parameter types
1. Path parameters
- Will appear on the url
parameter
- Will appear on the url
- So you can sign the url together
request body parameters (body)
- You can sort the post requested data data, then splice it into a string and sign it with other parameters.
Prevent repeated requests
- You can add a timestamp, and the same request within 1 minute will not be released if it is a duplicate request.
- Add a unique id to each request, save it to redis to set it to expire in 1 minute
Key
Because the encryption algorithm is public, we can add a key to enter the signature, so that even if the other party knows the encryption algorithm of the signature, it is impossible to change the request without the key.
- RSA encryption algorithm (asymmetric encryption algorithm)
- Increase security by encrypting the private key with public key and decrypting it.
- Simplified: You can also use random numbers as keys, which makes the security factor lower, but it is easy to implement.
encryption
- Select the MD5 algorithm to encrypt the parameters, and the js-md5 library will be used.
After the above review, we can roughly understand that the parameters that can be modified need to be encrypted into signatures.
Signature: MD5(postData? + url + timestamp + request unique id + key)
2. Vue implements adding request signature
The code is as follows:
3. Axios request interceptor implementation
import axios from 'axios" import {signatureGenerate} from "../utils/signatureUtil" const request = new ({ timeout: 3000 }) // Request an interceptor((config) => { // Get the request header parameters const {signature, timestamp, secret} = signatureGenerate(config) // Add the signature, key, and timestamp to the request header respectively if(signature) ["signature"] = signature if(secret) ["key"] = secret if(timestamp) ["timestamp"] = timestamp // No unique id of request was added here. You can implement the following by yourself. The author is lazy ~ ~ return config }); export default request
4. Generate signature tool class
// import md5 from "js-md5"; export function signatureGenerate({data, url, headers}){ // Parameter signature Key + timestamp + header parameter + url // Key let secret = ().toString(36).substr(2) // Time stamp let timestamp = new Date().getTime() // token let token = // Post parameters let dataStr = dataSerialize(dataSort(data)) // Generate a signature let str = dataStr + "secret=" + secret + "&timestamp=" + timestamp + "&url=" + url const sign = md5(str) return { signature: (), // Convert the signature to capital timestamp, secret } } // Parameter sortingfunction dataSort(obj){ if ((obj) == "{}" || obj == null) { return {} } let key = (obj)?.sort() let newObj = {} for (let i = 0; i < ; i++) { newObj[key[i]] = obj[key[i]] } return newObj } // Parameter serializationfunction dataSerialize(sortObj){ let strJoin = '' for(let key in sortObj){ strJoin += key + "=" + sortObj[key] + "&" } // return (0, - 1) return strJoin }
summary:
In fact, the front-end implementation is relatively simple, but it can continue to encapsulate axios. In fact, not all requests require signatures. Everyone can think about it themselves~~
My problem is that it was wasted a lot of time when getting these parameters stuck in the backend.
The implementation of backend API interface verification signature verification will be released one after another!
The request parameters are sorted from small to large according to the ASCII code and then added the secret key and then encrypted to obtain the signature value.
Recently, I have been connecting with banks to some interfaces. Party A's requirements for our interface data are as follows:
1. Both parties need to use https two-way authentication to transmit data.
2. The request parameters are encrypted in full packets
3. The request parameters are sorted from small to large according to the ASCII code and then added the secret key and then encrypted to obtain the signature value.
This article mainly introduces the signature generation tool code;
Step 1:
- After sorting all incoming parameters from small to large (dictionary order) according to the ASCII code of the field name, use the format of the URL key-value pair (i.e. key1=value1&key2=value2...) to splice into the character string1.
- Note: empty parameters do not participate in the signature.
Step 2:
- In the first step, string1 finally spliced with key=Key(key) to get the stringSignTemp string, and perform md5 operation on stringSignTemp, and then convert all characters of the obtained string into capitalization to get the sign value signValue.
- Note: KEY can be up to 32 characters (not including special symbols)
Code implementation
1. Convert the corresponding model to map
public static Map<String, Object> objectToMap(Object obj) throws Exception { if (obj == null) return null; TreeMap<String, Object> map = new HashMap<String, Object>(); BeanInfo beanInfo = (()); PropertyDescriptor[] propertyDescriptors = (); for (PropertyDescriptor property : propertyDescriptors) { String key = (); if (("class") == 0) { continue; } Method getter = (); Object value = getter != null ? (obj) : null; (key, value); } return map; }
Note: After the entity is converted through the above tool class, it has been sorted according to the ACII code of the parameter.
2. Generate signature tool class
package ; import ; import ; import ; import ; import ; import ; import ; /** * @author zhenghao * @description: * @date 2019/7/3014:33 */ public class SignatureUntils { /** * Generate signature; * * @param params * @return */ static public String signForInspiry(Map params, String key) { StringBuffer sbkey = new StringBuffer(); Set es = (); Iterator it = (); while (()) { entry = () (); String k = (String) (); Object v = (); //Null value is not passed, does not participate in the signature group string if (null != v && !"".equals(v)) { (k + "=" + v + "&"); } } (sbkey); sbkey = ("key=" + key); //MD5 encryption, the result is converted to uppercase characters String sign = toMD5(()).toUpperCase(); return sign; } /** * MD5 encryption of strings * * @param str string that needs to be encrypted * @return Lowercase MD5 string 32 bits */ public static String toMd5(String str) { String re = null; byte encrypt[]; try { byte[] tem = (); MessageDigest md5 = ("md5"); (); (tem); encrypt = (); StringBuilder sb = new StringBuilder(); for (byte t : encrypt) { String s = (t & 0xFF); if (() == 1) { s = "0" + s; } (s); } re = (); } catch (NoSuchAlgorithmException e) { (); } return re; } }
3. Test code
public static void testSingn(){ try { Row row = new Row(); ("1"); ("2019"); ("123"); ("344"); Map<String, Object> map = (row); String qwertyu = (map, "123456"); } catch (Exception e) { (); } }
4. If the parameters are directly mapped, an ordered map is needed.
SortedMap<Object,Object> params = new TreeMap<Object,Object>(); ("id",appid); ("name",name); ("age",age); ("sign",signForInspiry(params,"123456"));
The method to get the signature is completed here.
Summarize
The above is personal experience. I hope you can give you a reference and I hope you can support me more.