Ruby 语言 编写 API 接口签名验证 时间戳 + 随机数 + 参数哈希

Ruby阿木 发布于 2 天前 3 次阅读


Ruby API 接口签名验证实现

在互联网应用中,API(应用程序编程接口)是连接前后端、不同服务之间的重要桥梁。为了保证API调用的安全性,防止恶意攻击和数据篡改,通常会在API接口中加入签名验证机制。本文将围绕Ruby语言,实现一个基于时间戳、随机数和参数哈希的API接口签名验证方案。

签名验证原理

签名验证的基本原理是:客户端在发送请求时,将请求参数按照一定的规则进行排序、拼接,并生成一个签名值。服务器端接收到请求后,按照相同的规则对请求参数进行排序、拼接,并计算签名值,与客户端发送的签名值进行比对。如果两者一致,则验证成功,否则验证失败。

实现步骤

1. 定义签名算法

我们需要定义一个签名算法,用于生成和验证签名值。这里我们采用MD5算法进行签名。

2. 客户端实现

在客户端,我们需要实现以下功能:

- 对请求参数进行排序、拼接;
- 生成签名值;
- 将签名值附加到请求中发送。

以下是客户端的Ruby代码实现:

ruby
require 'digest'

class ApiClient
def initialize(app_key, app_secret)
@app_key = app_key
@app_secret = app_secret
end

def sign(params)
sorted_params = params.sort.to_h
query_string = sorted_params.map { |k, v| "{k}={v}" }.join('&')
timestamp = Time.now.to_i
nonce = SecureRandom.hex(16)
string_to_sign = "{@app_key}&{timestamp}&{nonce}&{query_string}&{@app_secret}"
Digest::MD5.hexdigest(string_to_sign)
end

def request(url, params)
params[:sign] = sign(params)
HTTParty.post(url, body: params.to_json, headers: { 'Content-Type' => 'application/json' })
end
end

3. 服务器端实现

在服务器端,我们需要实现以下功能:

- 接收请求,提取签名值;
- 对请求参数进行排序、拼接;
- 计算签名值,与客户端发送的签名值进行比对;
- 如果验证成功,处理请求;否则,返回错误信息。

以下是服务器端的Ruby代码实现:

ruby
require 'digest'

class ApiServer
def initialize(app_key, app_secret)
@app_key = app_key
@app_secret = app_secret
end

def verify_sign(params, sign)
timestamp = params[:timestamp]
nonce = params[:nonce]
query_string = params[:query_string]
string_to_sign = "{@app_key}&{timestamp}&{nonce}&{query_string}&{@app_secret}"
Digest::MD5.hexdigest(string_to_sign) == sign
end

def handle_request(params)
if verify_sign(params, params[:sign])
处理请求
puts 'Request verified successfully.'
else
puts 'Request verification failed.'
return { error: 'Invalid signature' }
end
end
end

4. 测试

为了验证我们的签名验证机制,我们可以进行以下测试:

- 测试签名验证成功的情况;
- 测试签名验证失败的情况(例如:签名值错误、参数顺序错误等)。

以下是测试代码:

ruby
client = ApiClient.new('app_key', 'app_secret')
server = ApiServer.new('app_key', 'app_secret')

测试签名验证成功
params = {
timestamp: Time.now.to_i,
nonce: SecureRandom.hex(16),
query_string: 'name=John&age=30',
sign: client.sign(params)
}
puts server.handle_request(params)

测试签名验证失败
params[:sign] = 'invalid_sign'
puts server.handle_request(params)

总结

本文介绍了基于Ruby语言的API接口签名验证实现方法。通过时间戳、随机数和参数哈希,我们可以有效地保证API调用的安全性。在实际应用中,可以根据具体需求调整签名算法和验证规则,以适应不同的场景。