背景
华为快应用接入支付服务3.0时,为了确保交易的安全性,有几个接口返回结果都需要进行签名校验。一般签名校验都是在开发者服务器上要实现的。那如果业务没有服务器,想进行签名校验,可以做到吗?
华为云函数就可以帮你解决这个问题,开发者无需自建服务器,只需聚焦业务逻辑、开发并上传函数代码,然后调用云函数帮你实现你要的功能。使用云函数可以帮助开发者大幅简化应用开发与传统运维相关的事务,降低应用功能的实现门槛,快速构建业务能力。
华为快应用也是支持云函数使用的,今天我们就结合应用内支付3.0接口来介绍如何使用云函数进行签名校验。
在正式介绍使用云函数进行签名校验前,请您先到华为开发者官网上学习快应用接入云函数慕课指导,了解什么是云函数、以及使用云函数需要配置哪些东西、如何创建一个快应用Serverless项目。本文默认您已经创建了一个Serverless项目并集成了Serverless sdk,重点介绍云函数中引用第三方js进行签名校验,下图是我的云函数项目结构。

图1 项目结构
cloudfunctions/checkrsasign 就是签名校验云函数。因为使用了第三方js,所以需要在该云函数目录下,执行npm命令下载并引用第三方依赖,上传云函数时华为IDE会将该云函数整个目录打包成函数部署包上传。具体步骤如下:
1. 初始化云函数三方依赖:进入checkrsasign目录,执行npm init命令初始化,执行完成后,checkrsasign目录下会生成package.json文件,见下图:

2. 安装第三方js:使用npm命令安装第三方签名校验的js依赖node-rsa,见下图:

执行完安装命令后,在package.json文件中会添加node-rsa的依赖,并同时将依赖模块下载下来。
3. 签名校验云函数实现:主要是node-rsa的使用,handler.js代码如下:
- //handler.js is a demo for handler function.
-
- let myHandler = function(event, context, callback, logger) {
- let res = new context.HTTPResponse({"simple": "example"}, {
- "res-type": "simple example",
- "faas-content-type": "json"
- }, "application/json", "200");
-
- const iapPublicKey='MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAgRTXdSeJNOcqTuzUnYJwvKO2QxJuRsrEAC+VFJTIxV/OXsjZK8KQHWe3HGJTYJ3RSZ0GNiEIsdNpyofzJv0bzyodPH4KlnorsUcczhYhuWSUpdP7fleTEmj7+2Meg1MnKIADIuIHMo0gJV4u1lMp4tL/5l2XbRI9fHFZv2EPccAkcIILkbPzyZ4rCsEpD3kLEaUftag3ICZcAbxrl85vE3vhFfa/JpQRr13BN+uDPIevMrFjNr5DPZyjOZsQcS/pcND6pt7dCpKkgBZk0OOSz8CET1nQln6EJXg/zGspXYUk5tIXQZhVopyQX1h2JlPlV5MAbsjwliLf0+ULXdzaRz4ony8QzWBth8jNyyoTaWKWlpi6LP5e117Yx7LYkUwvRH7u0dmGBhO0u9de6W08Cj9BGJ+w0nEoKoaqak98Id2de1tiToWuieetBfTzWjjjbzWpUneKQ7WycwMLymuVVAFW9EXl+bAHNVGnjjjEEWRlKwCe+2WKyrMrbfH+tr6tAgMBAAE=';
-
- var content;
- if (event.body) {
- logger.info(event.body);
- var _body = JSON.parse(event.body);
- logger.info(" check rsa sign handler _body="+_body);
- content = JSON.parse(_body.reqBody);
- } else {
- content = JSON.parse(event.content);
- }
-
- var body = {
- result:''
- };
- let payType=content.payType;
- body.result=checkSign(content.signContent,content.sign,payType);
- res.body = body;
- //send response
- callback(res);
-
- function checkSign(content,sign,payType){
- const NodeRSA = require("node-rsa");
- console.info("checkSign NodeRSA="+NodeRSA);
- let userPublicKey;
- if(payType==='iap4'){
- userPublicKey = `-----BEGIN PUBLIC KEY-----${iapPublicKey}-----END PUBLIC KEY-----`;
- }
-
- const key = new NodeRSA();
- key.setOptions({ b: 2048, signingScheme: "sha256"});
- key.importKey(userPublicKey, "pkcs8-public"); //导入密钥并设定格式
- let buffer = Buffer.from(content);
- let re=key.verify(buffer,sign,'Buffer','BASE64');
- return re;
- }
- };
-
- module.exports.myHandler = myHandler;
代码完成后,记得要将函数同步到云端的,否则客户端调用是不生效的。
4. 客户端初始化agc:在客户端调用云函数前,请确保您已经集成了Serverless sdk,具体参考官网说明。集成完sdk后,需要初始化agc,本示例demo中是在app.ux中完成。
app.ux代码:
- <script>
- const injectRef = Object.getPrototypeOf(global) || global;
- // 注入regeneratorRuntime
- injectRef.regeneratorRuntime = require('@babel/runtime/regenerator');
- import agconnect from "@agconnect/api";
- import "@agconnect/instance";
- import "@agconnect/function";
- const agconnectConfig = require('../agconnect-services.json');
- module.exports = {
- onCreate() {
- console.info('Application onCreate');
- agconnect.instance().configInstance(agconnectConfig);
- },
- onDestroy() {
- console.info('Application onDestroy');
- },
- dataApp: {
- localeData: {}
- },
- agc: agconnect
- }
- </script>
5、客户端调用签名校验云函数:将待签名内容signData及华为支付服务器返回的签名signStr,传递给云函数。具体调用代码如下:
- checkSign(signData, signStr) {
- console.info("checkSign sign signContent=" + signData + ", id=");
- console.info("checkSign sign =" + signStr);
- let agconnect = this.$app.$def.agc;
- let content = { signContent: signData, sign: signStr, payType: "iap4" };
- let body = { reqBody: JSON.stringify(content) };
- // xx 替换成云函数别名
- let functionCallable = agconnect.function().wrap("xxx");
- console.info("checkSign body=" + body);
- functionCallable.call(body).then(res => {
- console.log("checkSign res=" + JSON.stringify(res.responseBody));
- let result = res.responseBody.result;
- console.info("checkSign result =" + result);
-
- if(result){
- //签名校验返回正确
- }else{
- //签名校验返回失败
- }
-
- });
- },
快应用的云函数是基于node js环境的,有些第三方js如果不能在快应用客户端直接使用,都可以尝试使用云函数来实现解决您的问题,非常方便。