You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NodeJS如何获取PHP设置的Session变量?Stripe验证后更新MySQL

解决Stripe验证后NodeJS获取PHP会话用户ID并更新MySQL的问题

首先明确:PHP和NodeJS是独立的服务,默认各自的会话系统不互通,不能直接"获取PHP的Session变量",可通过以下几种可行方案解决:

方案1:用共享会话存储(推荐,适合长期维护)

把PHP和NodeJS的会话都存在同一个Redis实例里,实现跨服务会话共享:

步骤1:配置PHP使用Redis存储会话

修改php.ini或在PHP代码中设置:

// PHP代码中配置会话存储为Redis
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://127.0.0.1:6379');
// 正常启动会话并设置用户ID
session_start();
$_SESSION['user_id'] = 123; // 替换为你的实际用户ID

步骤2:NodeJS读取Redis中的会话数据

先安装依赖:

npm install redis express-session connect-redis mysql2

然后在NodeJS代码中连接Redis并处理Stripe回调:

const express = require('express');
const session = require('express-session');
const RedisStore = require('connect-redis').default;
const { createClient } = require('redis');
const mysql = require('mysql2/promise');
const stripe = require('stripe')('你的Stripe Secret Key');

// 创建Redis客户端
const redisClient = createClient({ url: 'redis://127.0.0.1:6379' });
redisClient.connect().catch(console.error);

const app = express();

// 配置会话中间件,和PHP保持一致的会话密钥、Cookie名
app.use(session({
  store: new RedisStore({ client: redisClient }),
  secret: '你的PHP会话密钥(对应php.ini的session.secret)',
  resave: false,
  saveUninitialized: false,
  cookie: {
    sameSite: 'lax',
    httpOnly: true,
    maxAge: 86400000 // 和PHP会话过期时间保持一致
  },
  name: 'PHPSESSID' // 使用PHP默认的会话Cookie名
}));

// 处理Stripe Webhook回调
app.post('/stripe-webhook', express.raw({type: 'application/json'}), async (req, res) => {
  const sig = req.headers['stripe-signature'];
  const event = stripe.webhooks.constructEvent(req.body, sig, '你的Stripe Webhook密钥');

  if (event.type === 'identity.verification_session.verified') {
    // 从共享会话中获取用户ID
    const userId = req.session.user_id;
    if (!userId) {
      return res.status(400).send('用户ID未找到');
    }

    // 更新MySQL数据库
    const connection = await mysql.createConnection({
      host: '你的数据库地址',
      user: '数据库用户名',
      password: '数据库密码',
      database: '数据库名'
    });
    await connection.execute('UPDATE users SET verified = 1 WHERE id = ?', [userId]);
    await connection.end();

    res.json({ received: true });
  } else {
    res.status(400).send(`Unhandled event type ${event.type}`);
  }
});

app.listen(3000);

方案2:通过Stripe Metadata传递用户ID(更简单,无需共享会话)

创建Stripe Identity验证会话时,将用户ID存入metadata,验证成功后Stripe会在Webhook回调中返回该数据:

步骤1:PHP创建验证会话时添加metadata

require 'vendor/autoload.php';
$stripe = new \Stripe\StripeClient('你的Stripe Secret Key');

session_start();
$userId = $_SESSION['user_id'];

$verificationSession = $stripe->identity->verificationSessions->create([
  'type' => 'document',
  'metadata' => [
    'user_id' => $userId // 将用户ID存入metadata
  ],
  'return_url' => 'https://你的域名/验证完成页'
]);

// 跳转至Stripe验证页面
header("Location: " . $verificationSession->url);

步骤2:NodeJS在Webhook中获取metadata并更新数据库

const stripe = require('stripe')('你的Stripe Secret Key');
const express = require('express');
const mysql = require('mysql2/promise');

const app = express();

app.post('/stripe-webhook', express.raw({type: 'application/json'}), async (req, res) => {
  const sig = req.headers['stripe-signature'];
  const event = stripe.webhooks.constructEvent(req.body, sig, '你的Stripe Webhook密钥');

  if (event.type === 'identity.verification_session.verified') {
    const verificationSession = event.data.object;
    const userId = verificationSession.metadata.user_id; // 从metadata提取用户ID

    if (!userId) {
      return res.status(400).send('用户ID未找到');
    }

    // 更新MySQL数据库
    const connection = await mysql.createConnection({
      host: '你的数据库地址',
      user: '数据库用户名',
      password: '数据库密码',
      database: '数据库名'
    });
    await connection.execute('UPDATE users SET verified = 1 WHERE id = ?', [userId]);
    await connection.end();

    res.json({ received: true });
  } else {
    res.status(400).send(`Unhandled event type ${event.type}`);
  }
});

app.listen(3000);

方案3:解析PHP会话文件(仅适合临时测试,不推荐生产)

如果PHP默认用文件存储会话,NodeJS可读取服务器上的会话文件并解析:

步骤1:确认PHP会话存储路径

Linux环境下默认路径一般为/var/lib/php/sessions/,可通过phpinfo()查看session.save_path的值。

步骤2:NodeJS读取并解析会话文件

const fs = require('fs');
const path = require('path');
const mysql = require('mysql2/promise');
const express = require('express');
const stripe = require('stripe')('你的Stripe Secret Key');

const app = express();
const phpSessionPath = '/var/lib/php/sessions/'; // 替换为你的PHP会话路径

app.post('/stripe-webhook', express.raw({type: 'application/json'}), async (req, res) => {
  const sig = req.headers['stripe-signature'];
  const event = stripe.webhooks.constructEvent(req.body, sig, '你的Stripe Webhook密钥');

  if (event.type === 'identity.verification_session.verified') {
    // 从Cookie获取PHP会话ID
    const phpSessId = req.cookies.PHPSESSID;
    if (!phpSessId) {
      return res.status(400).send('会话ID未找到');
    }

    // 读取并解析会话文件
    const sessionFilePath = path.join(phpSessionPath, `sess_${phpSessId}`);
    try {
      const sessionData = fs.readFileSync(sessionFilePath, 'utf8');
      const sessionObj = {};
      sessionData.split(';').forEach(item => {
        if (!item) return;
        const [key, valuePart] = item.split('|');
        if (valuePart.startsWith('s:')) {
          sessionObj[key] = valuePart.slice(2, -2); // 解析字符串类型的会话值
        }
      });
      const userId = sessionObj.user_id;

      if (!userId) {
        return res.status(400).send('用户ID未找到');
      }

      // 更新MySQL数据库
      const connection = await mysql.createConnection({
        host: '你的数据库地址',
        user: '数据库用户名',
        password: '数据库密码',
        database: '数据库名'
      });
      await connection.execute('UPDATE users SET verified = 1 WHERE id = ?', [userId]);
      await connection.end();

      res.json({ received: true });
    } catch (err) {
      console.error(err);
      res.status(500).send('读取会话失败');
    }
  } else {
    res.status(400).send(`Unhandled event type ${event.type}`);
  }
});

app.listen(3000);

注意:方案3存在权限问题(NodeJS进程需有权限读取PHP会话目录),且会话格式可能随PHP版本变化,生产环境优先选用方案1或2。

内容的提问来源于stack exchange,提问作者Ironflipper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 02:25:28