我们一般在请求头中添加一些信息来保证验证请求身份,这里涉及到四个字段值(如nonce和timestamp不传则不参与签名,使用验签算法二):
appId: 软件Id
nonce:随机字符串
timestamp:时间戳
signature:签名
代码如下:
@Component
public class CommonApiAuthGatewayFilterFactory extends AbstractGatewayFilterFactory
验签算法一:
public static boolean validateSignature(String appId, long timestamp, String nonce, String httpmethod,String httpurl, String signature) {
String str = appId + "|" + nonce + "|" + timestamp + "|" + httpmethod.concat("|").concat(httpurl);
String encryptBASE64 = encryptBASE64(sha256(str.getBytes()));
log.debug("signature: {}, encryptBASE64: {}", signature, encryptBASE64);
return Arrays.equals(encryptBASE64.getBytes(), signature.getBytes());
}
验签算法二(请求头不传nonce和timestamp则不参与签名):
public static boolean validateSignature(String appId, String httpmethod, String httpurl, String signature) {
String s2 = httpmethod.concat("&").concat(httpurl).concat("&").concat("app_id=" + appId);
String encryptBASE64 = encryptbase64(SHA1(s2.getBytes()));
byte[] signature2 = encryptBASE64.getBytes();
return Arrays.equals(signature2, signature.getBytes());
}
前端请求时请求头加入对应信息:
request.interceptors.request.use(config => {
const token = storage.get(ACCESS_TOKEN)
if (token) {
config.headers['Access-Token'] = token
}
const url = config.url.split('?')[0]
const appId = '123456789'
const timestamp = new Date().getTime()
const nonce = generateNonce(timestamp)
const signature = generateSignature(appId, timestamp, nonce, config.method.toUpperCase(), url)
config.headers.appId = appId
config.headers.signature = signature
config.headers.nonce = nonce
config.headers.timestamp = timestamp
return config
}, errorHandler)
export const generateSignature = (appId, timestamp, nonce, httpMethod, httpURL) => {
const str = appId + '|' + nonce + '|' + timestamp + '|' + httpMethod + '|' + httpURL
let result = SHA256(str)
if (result) {
result = strToBase64(result)
}
return result
}
export const generateNonce = (theServerTime) => {
const randomNumber = []
for (let i = 0; i < 8; i++) {
const oneRandom = random(-128, 127)
randomNumber.push(oneRandom)
}
let timeStamp = Math.floor(new Date().getTime() / 60000)
if (theServerTime !== 0) {
timeStamp = Math.floor(theServerTime / 60000)
}
const nt = []
nt[3] = timeStamp & 0xff
nt[2] = (timeStamp >> 8) & 0xff
nt[1] = (timeStamp >> 16) & 0xff
nt[0] = (timeStamp >> 24) & 0xff
for (let x = 0; x < nt.length; x++) {
randomNumber.push(nt[x])
}
return bytesToBase64(randomNumber)
}