在现代互联网应用中,RESTful API 成为了前后端数据交互的主要方式。由于客户端可以直接请求 API 接口,因此一些敏感数据很容易被黑客窃取或者篡改。为了保障 API 接口的安全性,需要在 API 中引入签名机制。
签名机制是指客户端在请求 API 时,在某些特定参数的基础上生成一个签名,然后将该签名一起发送到服务端。服务端根据一定的规则计算出该签名,并与客户端的签名进行比较,判断请求是否合法。
本篇文章将介绍如何在 RESTful API 中实现签名机制,旨在为前端开发人员提供指导和参考。
签名机制的流程
签名机制需要组成三个方面的流程:签名参数的计算、签名的发送和签名的验证。下面我们逐一介绍这些流程的具体实现。
签名参数的计算
签名参数的计算是生成签名的基础,签名所用的参数称为签名参数。签名参数一般是一些敏感数据,如秘钥、时间戳、随机数等。
以 Node.js 为例,可以基于以下代码生成签名参数:
// javascriptcn.com 代码示例 const crypto = require('crypto'); const secretKey = 'ABCD1234'; // 签名秘钥 const timestamp = Math.floor(Date.now() / 1000); // 时间戳 const nonce = Math.random().toString(36).substr(2); // 随机数 const params = { secretKey, timestamp, nonce }; // 签名参数 // 使用 SHA1 计算签名 const hash = crypto.createHash('sha1').update(JSON.stringify(params)).digest('hex');
在这个例子中,我们使用 Node.js 的 crypto
模块计算了一个基于时间戳和随机数的签名参数,并使用 SHA1 哈希算法对参数进行加密。
签名的发送
签名参数计算完成后,客户端需要将其与请求数据一起发送到服务器。一般来说,请求数据是由 GET 或 POST 方法传递到服务器的。对于 POST 方法,可以将签名参数作为请求数据的一部分传递。对于 GET 方法,可以将签名参数添加到请求 URL 的 query 参数里。
以下是 POST 方法的示例代码:
// javascriptcn.com 代码示例 const formData = new FormData(); formData.append('secretKey', secretKey); formData.append('timestamp', timestamp); formData.append('nonce', nonce); formData.append('signature', hash); fetch('/api', { method: 'post', body: formData, });
转换成 jQuery 的形式如下:
// javascriptcn.com 代码示例 $.ajax({ url: '/api', type: 'post', data: { secretKey, timestamp, nonce, signature: hash }, processData: false, contentType: false, success: () => {}, error: () => {}, });
对于 GET 方法,可以将签名参数拼接到请求 URL 的 query 参数里,形如:
/api?secretKey=ABCD1234×tamp=1597285269&nonce=agu65n&signature=dfe3d3b81f3e3885e6cac5f6a16a88fcc9c6a5a1
签名的验证
签名的验证是 API 接口必须进行的操作,通过该操作可以判断是否为合法请求。在服务端中,采用与客户端一致的方式计算签名,并与客户端传的签名进行比较。如果两个签名相同,则代表请求合法;如果不相同,则认为请求不合法,返回错误状态码(如 401 Unauthorized
)。
在 Node.js 中,可以按照以下代码实现签名验证的逻辑:
// javascriptcn.com 代码示例 const url = require('url'); // 服务端请求处理逻辑 function handleRequest(req, res) { // 获取签名参数 const query = url.parse(req.url, true).query; const { secretKey, timestamp, nonce, signature } = query; // 计算签名 const params = { secretKey, timestamp, nonce }; const hash = crypto.createHash('sha1').update(JSON.stringify(params)).digest('hex'); // 验证签名是否合法 if (hash !== signature) { res.writeHead(401, { 'Content-Type': 'text/plain' }); res.end('Unauthorized'); } else { // 接口操作 // ... } }
总结
以上便是 RESTful API 签名机制的实现逻辑。通过引入签名机制,可以有效保证 API 接口的安全性,防止恶意请求和数据篡改。同时,也为前端开发人员提供了一种有效的数据交互模式。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/652f73f17d4982a6eb095bf2