当前位置:首页 » 《随便一记》 » 正文

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

26 人参与  2024年10月07日 16:40  分类 : 《随便一记》  评论

点击全文阅读


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

最近在搞苹果内购,是使用微信提供的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://m.zhangshiyu.com/post/168673.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

最新文章

  • 祖母寿宴,侯府冒牌嫡女被打脸了(沈屿安秦秀婉)阅读 -
  • 《雕花锦年,昭都旧梦》(裴辞鹤昭都)完结版小说全文免费阅读_最新热门小说《雕花锦年,昭都旧梦》(裴辞鹤昭都) -
  • 郊区41号(许洛竹王云云)完整版免费阅读_最新全本小说郊区41号(许洛竹王云云) -
  • 负我情深几许(白诗茵陆司宴)完结版小说阅读_最热门小说排行榜负我情深几许白诗茵陆司宴 -
  • 九胞胎孕妇赖上我萱萱蓉蓉免费阅读全文_免费小说在线看九胞胎孕妇赖上我萱萱蓉蓉 -
  • 为保白月光,侯爷拿我抵了债(谢景安花田)小说完结版_完结版小说全文免费阅读为保白月光,侯爷拿我抵了债谢景安花田 -
  • 陆望程映川上官硕《我的阿爹是带攻略系统的替身》最新章节阅读_(我的阿爹是带攻略系统的替身)全章节免费在线阅读陆望程映川上官硕
  • 郑雅琴魏旭明免费阅读_郑雅琴魏旭明小说全文阅读笔趣阁
  • 头条热门小说《乔书意贺宴临(乔书意贺宴临)》乔书意贺宴临(全集完整小说大结局)全文阅读笔趣阁
  • 完结好看小说跨年夜,老婆初恋送儿子故意出车祸_沈月柔林瀚枫完结的小说免费阅读推荐
  • 热推《郑雅琴魏旭明》郑雅琴魏旭明~小说全文阅读~完本【已完结】笔趣阁
  • 《你的遗憾与我无关》宋怀川冯洛洛无弹窗小说免费阅读_免费小说大全《你的遗憾与我无关》宋怀川冯洛洛 -

    关于我们 | 我要投稿 | 免责申明

    Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1