成功购买后如何阻止 Stripe 覆盖客户端的会话 cookie

2024-01-31

环境:快速、快速会话、Stripe

在下面的简化示例中,当用户请求主页时express-session为用户分配一个会话 cookie。刷新页面会保留与访问成功或失败路由相同的会话 ID。单击升级按钮会将客户端带到 Stripe 购物车屏幕,该屏幕也保留相同的会话 ID。然而,一旦用户进入 Stripe 购物车并成功购买,他就会被转发到成功路线,并且会话 ID 会被 Stripe 覆盖。在完整版本中,这是一个问题,因为用户将登录,这会导致用户在成功购买后自动注销。我不确定为什么会发生这种情况或如何阻止它。

app.js

const bodyParser = require('body-parser');
require('dotenv').config();
const express = require('express');
const session = require('express-session');
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

const app = express();

app.set('view engine', 'ejs');

app.use(express.static('views'));

app.use(
    session({
        maxAge: 24 * 60 * 60 * 1000,
        name: 'randomName',
        resave: false,
        saveUninitialized: true,
        secret: 'randomSecret',
        cookie: {
            sameSite: true,
            secure: false
        } 
    })
);

app.get('/', function(req, res) {

    req.session.userValues = true;
    console.log(req.session);

    res.render('index', { stripePublicKey: process.env.STRIPE_PUBLIC_KEY });
});

app.get('/success', function(req, res) {

    console.log(req.session);

    res.render('success');
});    

app.get('/fail', function(req, res) {

    console.log(req.session);

    res.render('fail');
});

app.post('/create-checkout-session', bodyParser.raw({ type: 'application/json' }), async function(req, res) {

    console.log(req.session);

    const session = await stripe.checkout.sessions.create({
        submit_type: 'auto',
        payment_method_types: ['card'],
        line_items: [
            {
                price_data: {
                    currency: 'usd',
                    product_data: {
                        name: 'name of product',
                        description: 'description of product'
                    },
                    unit_amount: 100
                },
                quantity: 1,
            }
        ],
        locale: 'en',
        mode: 'payment',
        success_url: 'http://localhost:8080/success',
        cancel_url: 'http://localhost:8080/fail'
    });

    res.json({ id: session.id });
});    

app.listen(8080, function() {
    console.log('listening on port 8080');
});

index.js

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Upgrade</title>
    <script>var stripePublicKey = '<%- stripePublicKey %>';</script>
    <script defer src="https://js.stripe.com/v3/"></script>
    <script defer src="checkout.js"></script>
</head>
<body>
    
    <button id="checkout-button">upgrade premium</button>

</body>
</html>

结账.js

var stripe = Stripe(stripePublicKey);

var checkoutButton = document.getElementById('checkout-button');

checkoutButton.addEventListener('click', checkoutSequence);

function checkoutSequence() {

    fetch('/create-checkout-session', {
        method: 'POST',
    })
    .then(function(response) {
        return response.json();
    })
    .then(function(session) {
        console.log(session);
        return stripe.redirectToCheckout({ sessionId: session.id });
    })
    .then(function(result) {
        if (result.error) {
            alert(result.error.message);
        }
    })
    .catch(function(error) {
        console.error('Error:', error);
    });
}

经过6个小时的测试,我发现了问题所在。cookie.sameSite必须设置为lax代替true。显然,当 Stripe 走上成功之路时express-session确定这是来自外部站点并重置 cookie。

app.use(
    session({
        maxAge: 24 * 60 * 60 * 1000,
        name: 'randomName',
        resave: false,
        saveUninitialized: true,
        secret: 'randomSecret',
        cookie: {
            sameSite: 'lax',
            secure: false
        } 
    })
);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

成功购买后如何阻止 Stripe 覆盖客户端的会话 cookie 的相关文章

随机推荐