苹果内购的凭证验证和解密(前端和本地node服务)

苹果内购的凭证验证和解密

最近在搞苹果内购,是使用微信提供的Dount提供的小程序转成APP。苹果内购使用的也是他们封装好的js接口,然后后端在解析我传递的支付凭证的时候他一直解析不成功然后我坚信自己的传递参数没有问题,我就自己使用node写了一个本地服务去验证我的支付凭证,所以就有了这个文章。

服务器端代码 (server.mjs)

导入必要模块
import express from 'express';
import bodyParser from 'body-parser';
import cors from 'cors';
import fetch from 'node-fetch';
  • express: 用于创建一个服务器。
  • bodyParser: 用于解析JSON格式的请求体。
  • cors: 用于解决跨域问题。
  • fetch: 用于发送HTTP请求到Apple的验证服务器。
创建Express应用并配置中间件
const app = express();
const port = 3000;app.use(cors());
app.use(bodyParser.json());
  • 创建一个Express应用实例。
  • 设置应用端口为3000。
  • 使用cors中间件以允许跨域请求。
  • 使用bodyParser中间件以解析JSON格式的请求体。
定义路由以处理验证请求
app.post('/verifyReceipt', async (req, res) => {const { receiptData, password } = req.body;try {const response = await fetch('https://sandbox.itunes.apple.com/verifyReceipt', {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify({'receipt-data': receiptData,'password': password})});const result = await response.json();res.json(result);} catch (error) {res.status(500).json({ error: error.message });}
});
  • 定义一个POST路由/verifyReceipt来处理客户端发送的验证请求。
  • 从请求体中提取receiptDatapassword
  • 使用fetch函数发送POST请求到Apple的沙盒验证服务器https://sandbox.itunes.apple.com/verifyReceipt
  • 请求体包含Base64编码的收据数据和共享密钥。
  • 将Apple返回的结果以JSON格式响应回客户端。
  • 如果请求失败,返回500状态码和错误信息。
启动服务器
app.listen(port, () => {console.log(`Server is running on http://localhost:${port}`);
});
  • 启动服务器,并在指定端口上监听连接请求。
  • 要先进行下载这个几个依赖
npm install express body-parser cors node-fetch
  • 然后就是启动这个服务
node server.mjs

前端代码(HTML文件)

基本HTML结构和样式
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>验证苹果内购凭证</title><style>body {font-family: Arial, sans-serif;margin: 0;padding: 20px;background-color: #f0f0f0;}.container {max-width: 600px;margin: 0 auto;padding: 20px;background-color: white;border-radius: 8px;box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);}.container h1 {font-size: 24px;margin-bottom: 20px;}.container textarea {width: 100%;height: 100px;margin-bottom: 20px;padding: 10px;border: 1px solid #ccc;border-radius: 4px;font-family: monospace;}.container button {display: inline-block;padding: 10px 20px;background-color: #28a745;color: white;border: none;border-radius: 4px;cursor: pointer;font-size: 16px;}.container button:disabled {background-color: #ccc;}.container .result {margin-top: 20px;white-space: pre-wrap;word-wrap: break-word;background-color: #f8f9fa;padding: 10px;border: 1px solid #ccc;border-radius: 4px;font-family: monospace;}</style>
</head>
<body><div class="container"><h1>粘贴你的内购凭证(transactionReceipt)</h1><textarea id="receiptData" placeholder="粘贴你的内购凭证(transactionReceipt)"></textarea><button id="verifyButton" onclick="verifyReceipt()">解析凭证</button><div id="result" class="result"></div></div>
  • 设置HTML文档的基本结构和样式,确保页面看起来整洁美观。
JavaScript代码
  <script>async function verifyReceipt() {const receiptData = document.getElementById('receiptData').value;const resultElement = document.getElementById('result');const verifyButton = document.getElementById('verifyButton');if (!receiptData) {resultElement.textContent = '请输入base64编码的收据数据';return;}verifyButton.disabled = true;resultElement.textContent = '解析中...';try {const response = await fetch('http://localhost:3000/verifyReceipt', {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify({'receiptData': receiptData,'password': 'your-shared-secret' // 替换你的秘钥可有可无})});const result = await response.json();handleReceiptResult(result, resultElement);} catch (error) {resultElement.textContent = `Error: ${error.message}`;}verifyButton.disabled = false;}function handleReceiptResult(result, resultElement) {const status = result.status;let message;switch (status) {case 0:message = '验证成功!';break;case 21000:message = 'App Store无法读取你提供的JSON对象。';break;case 21002:message = '收到的数据无效。';break;case 21003:message = '收据无法被验证。';break;case 21004:message = '你提供的共享密钥与帐户文件中的共享密钥不匹配。';break;case 21005:message = '收据服务器当前不可用。';break;case 21006:message = '收据有效,但订阅已过期。';break;case 21007:message = '此收据来自测试环境,但已发送到生产环境进行验证。';break;case 21008:message = '此收据来自生产环境,但已发送到测试环境进行验证。';break;case 21010:message = '收据无效,无法被验证。';break;default:message = `未知错误,状态码:${status}`;}resultElement.textContent = `结果: ${JSON.stringify(result, null, 2)}\n\n信息: ${message}`;}</script>
</body>
</html>
  • verifyReceipt函数:当用户点击“解析凭证”按钮时,获取输入的收据数据,并发送POST请求到本地代理服务器(http://localhost:3000/verifyReceipt)。显示解析结果或错误信息。
  • handleReceiptResult函数:处理Apple返回的验证结果,根据状态码显示具体的错误消息。
    • 根据Apple内购验证API的状态码显示相应的信息,例如状态码0表示验证成功,状态码21000表示App Store无法读取你提供的JSON对象,等等。

作用

  • 服务器端代码

    • 接收客户端发送的请求,并将请求转发到Apple的验证服务器。
    • 处理Apple返回的结果,并将结果返回给客户端。
    • 通过设置CORS和解析JSON请求体,确保请求和响应的正确处理。
  • 前端代码

    • 提供用户界面,允许用户输入Base64编码的内购凭证。
    • 将用户输入的凭证发送到本地服务器进行验证。
    • 处理服务器返回的结果,并在页面上显示详细的验证结果和错误信息。

通过这种方式,用户可以方便地验证Apple内购凭证,并获取详细的验证结果和错误信息。这样可以帮助开发人员和用户了解验证过程中可能出现的问题,并采取相应的措施进行处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/36976.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

矩阵的奇异值(Singular Values)

矩阵的奇异值&#xff08;Singular Values&#xff09;是奇异值分解&#xff08;SVD&#xff09;过程中得到的一组重要特征值。它们在许多应用中非常重要&#xff0c;如信号处理、数据压缩和统计学等。以下是对奇异值及其计算和性质的详细解释&#xff1a; 奇异值分解&#xf…

Java--常用类

一、StringBuffer 1.1 概述 线程安全的可变字符序列。 一个类似于 String 的字符串缓冲区&#xff0c;但能修改。 但通过某些方法调用可以改变该序列的长度和内容。 1.2 创建对象 ​ public class Demo04 {public static void main(String[] args) {/**构造方法摘要 Stri…

【机器学习】在【PyCharm中的学习】:从【基础到进阶的全面指南】

目录 第一步&#xff1a;基础准备 1.1 Python基础 1.1.1 学习Python的基本语法 变量和数据类型&#xff1a; 1.1.2 控制流 条件语句&#xff1a; 循环语句&#xff1a; 1.1.3 函数和模块 函数&#xff1a; 模块&#xff1a; 1.2 安装PyCharm 1.2.1 下载并安装 第二…

Effective C++ 改善程序与设计的55个具体做法笔记与心得 9

九. 杂项讨论 53. 不用轻忽编译器的警告 请记住&#xff1a; 严肃对待编译器发出的警告信息。努力在你的编译器的最高&#xff08;最严苛&#xff09;警告级别下争取“无任何警告”的荣誉。不要过度倚赖编译器的报警能力&#xff0c;因为不同的编译器对待事情的态度并不相同…

为什么接口返回的是二进制流的文件时,前端请求时responseType要设置成‘blob‘

当接口返回的是二进制流的文件时&#xff0c;前端在发起axios请求时需要设置responseType为blob&#xff0c;原因有以下几点 1、数据类型匹配&#xff1a; blob类型能够正确处理二进制数据。如果前端请求不设置responseType&#xff0c;默认情况下&#xff0c;浏览器会尝试解析…

在创意设计领域“刷屏”的人工智能生成内容(AIGC)是什么?

在创意设计领域“刷屏”的人工智能生成内容&#xff08;AIGC&#xff09;是什么&#xff1f;这是一个值得深入探讨的话题&#xff0c;它关乎技术的革新、创意的边界以及未来设计行业的走向。随着人工智能技术的飞速发展&#xff0c;AIGC&#xff08;Artificial Intelligence Ge…

k8s_docker和container的关系和区别

Docker 和 containerd 是容器生态系统中的两个重要组件&#xff0c;它们各自有不同的角色和职责。以下是对它们之间关系和区别的详细解释。 Docker 和 containerd 的关系 Docker&#xff1a; Docker 是一个完整的容器平台&#xff0c;提供了一系列工具来构建、分发和运行容器化…

聚鼎贸易:装饰画行业还有没有前景

在数字化的浪潮中&#xff0c;装饰画行业似乎被边缘化&#xff0c;成为传统与现代较量中的一片瓦砾。然而&#xff0c;透过表面的凋零&#xff0c;我们能够窥见其潜藏的蓬勃生机与无限前景。 随着社会的快速发展&#xff0c;人们对生活品质的追求日益提高。家&#xff0c;作为个…

Spring Cloud OpenFeign基础入门与使用实践总结

官网地址&#xff1a;https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/#spring-cloud-feign GitHub地址&#xff1a;https://github.com/spring-cloud/spring-cloud-openfeign 本文SpringCloud版本为&#xff1a; <spring.boot.version>3…

火锅食材配送小程序的作用有什么

火锅店、麻辣烫店、餐厅等对火锅丸子食材的需求量很高&#xff0c;还有普通消费者零售等&#xff0c;市场中或城市里总是有着较为知名的食材店或厂商&#xff0c;通过产品质量、口碑、宣传、老客复购等获得更多生意营收。 线下生意放缓&#xff0c;需要商家拓宽渠道。运用雨科…

2、网上图书订购

完整DDLDML SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS 0;-- ---------------------------- -- Table structure for administarators -- ---------------------------- DROP TABLE IF EXISTS administarators; CREATE TABLE administarators (admin_id int(11) NOT NULL AU…

搜维尔科技:SenseGlove Nova2国内首款支持手掌心力回馈手套开售

《SenseGlove Nova 2》现正全球发行中! 搜维尔科技独家代理最新上市的 SenseGlove Nova 2 是世上首款&#xff0c;也是目前市面上唯一一款提供手掌力回馈的无缐VR力回馈手套&#xff0c;它结合了三种最先进的反馈技术&#xff0c;包括主动反馈、强力反馈及震动反馈&#xff0c…

基于横纵向的混合联邦学习原理分析

近期陆续接触到关于混合联邦学习的概念&#xff0c;但基于横纵向的混合联邦实际的应用案例却几乎没有看到&#xff0c;普遍是一些实验性的课题&#xff0c;因此这一领域知识没有被很好普及。本篇文章的目的&#xff0c;主要是分析讨论关于横纵向混合联邦学习的业务场景、应用架…

nginx: [warn] 20240 worker_connections exceed open file resource limit: 1024

nginx: [warn] 20240 worker_connections exceed open file resource limit: 1024 报错翻译过来就是&#xff1a; nginx&#xff1a;[警告] 20240 worker_connections超出打开文件资源限制&#xff1a;1024 解决方法&#xff1a; 1.查看当前文件打开数量的限制 ulimit -S…

2024软博会

2024年&#xff0c;金秋的十月&#xff0c;青岛国际会展中心迎来了一年一度的科技盛宴——青岛国际软件融合创新博览会&#xff08;简称“青岛软博会”&#xff09;。这场为期三天的展会&#xff0c;不仅吸引了全球软件产业的目光&#xff0c;更成为了展示中国软件产业发展成果…

OpenHarmony南向驱动开发实战-Input

简介 该仓下主要包含Input模块HDI&#xff08;Hardware Driver Interface&#xff09;接口定义及其实现&#xff0c;对上层输入服务提供操作input设备的驱动能力接口&#xff0c;HDI接口主要包括如下三大类&#xff1a; InputManager&#xff1a;管理输入设备&#xff0c;包括…

数据库系统概论(超详解!!!) 第十四节 数据库恢复技术

1.事务的基本概念 1.事务 事务(Transaction)是用户定义的一个数据库操作序列&#xff0c;这些操作要么全做&#xff0c;要么全不做&#xff0c;是一个不可分割的工作单位。 事务和程序是两个概念&#xff0c; 在关系数据库中&#xff0c;一个事务可以是一条SQL语句&#xff…

rockey linux rpm安装mysql 8.4.0

背景介绍&#xff1a; 系统 rockey linux 9.4 mysql 8.4.0 我一开始想在系统上安装5.7的着&#xff0c;因为我有这个包&#xff0c;但是通过rpm安装的时候&#xff0c;到最后一步提示我没有/usbin/chkconfig 这个目录&#xff0c;怀疑是系统的问题&#xff0c;然后想安装chk…

未来先行!MWC 2024 世界移动通信大会盛大开幕!!!

2024MWC上海世界移动通信大会&#xff0c;在上海新国际博览中心&#xff08;SNIEC&#xff09;盛大开幕。 今年&#xff0c;MWC的主办方GSMA&#xff08;全球移动通信系统协会&#xff09;为这届MWC定下了一个主题——“Future First&#xff08;未来先行&#xff09;”。各大…

内网穿透技术

内网穿透&#xff08;NAT traversal&#xff09;是一种技术&#xff0c;用于实现公网与内网之间的通信连接。当内网中的设备无法直接从公网访问时&#xff0c;内网穿透技术可以通过一些手段&#xff0c;让公网上的设备能够穿透到内网中的设备&#xff0c;建立起通信连接。 说白…