重定向到条带后丢失会话数据

Posted

技术标签:

【中文标题】重定向到条带后丢失会话数据【英文标题】:lost the session data after redirecting to stripe 【发布时间】:2021-08-24 19:31:06 【问题描述】:

我正在 Spring MVC 中创建一个带有条带支付集成的食品订购系统。当我试图从之前设置的 webhook 控制器中的会话中获取属性时,我得到了 null。为什么?

最重要的是如何解决?

编辑:

这是我的支付意图控制器,由 client.js 文件调用,现在我在这里设置会话中的项目,此控制器将条带​​生成的客户端密码 id 返回给 client.js,现在是 client.js调用条带并成功付款,并在付款确认条带上向我发送一个带有 charge.succeeded 事件的本地主机端点上的 webhook。现在要处理该事件,我需要会话属性,但我无法从会话中获取它们,因为它返回 null。

支付意图控制器

@RestController public class PaymentController 
    @PostMapping("/create-payment-intent")
    public CreatePaymentResponse createPaymentIntent(@RequestBody CreatePayment createPayment, 
    HttpServletRequest req)
        throws StripeException 

    HttpSession session = req.getSession();

    ArrayList<String> items = new ArrayList<>();
    JsonItem[] jsonItems = createPayment.getItems();
    for (JsonItem jsonItem : jsonItems) 
        items.add(jsonItem.getItemid());
    

    session.setAttribute("pnames", items);

    Float amount = Float.parseFloat(createPayment.getAmount());
    System.out.println(amount.longValue() * 100l);
    PaymentIntentCreateParams createParams = new PaymentIntentCreateParams.Builder()
            .setCurrency("INR")
            .setAmount(amount.longValue() * 100L)
            .setDescription("product's amount")
            .build();

    PaymentIntent intent = PaymentIntent.create(createParams);
    CreatePaymentResponse paymentResponse = new CreatePaymentResponse(intent.getClientSecret());
    return paymentResponse;


这是我的 Webhook 控制器

    @RestController
    public class StripeWebhookController 

    @Autowired
    private FoodhubServiceImpl service;
    
    @Autowired
    private Payment payment;
    
    private String endpointSecret="some endpoint secret";
    
    
    @PostMapping("/foodhub/endpoint")
    public String handleStripeEvents(@RequestBody String payload, @RequestHeader("Stripe-Signature") String sigHeader,HttpServletRequest req) 
        
                HttpSession session = req.getSession();
                
                @SuppressWarnings("unchecked")
                ArrayList<String> arr = (ArrayList<String>) session.getAttribute("pnames");//null
                System.out.println(arr.get(0));//null pointer exception
                
                if(sigHeader == null) 
                    return "";
                
                
                Event event; 
      
                try 
                    event = Webhook.constructEvent(
                        payload, sigHeader, endpointSecret
                    );
                 catch (SignatureVerificationException e) 
                    // Invalid signature
                    System.out.println("Webhook error while validating signature.");
                    System.out.println(e);
                    return "";
                
                
            // Deserialize the nested object inside the event
            EventDataObjectDeserializer dataObjectDeserializer = event.getDataObjectDeserializer();
            StripeObject stripeObject = null;
            if (dataObjectDeserializer.getObject().isPresent()) 
                stripeObject = dataObjectDeserializer.getObject().get();
             else 
                // Deserialization failed, probably due to an API version mismatch.
                // Refer to the Javadoc documentation on `EventDataObjectDeserializer` for
                // instructions on how to handle this case, or return an error here.
            
            // Handle the event
            switch (event.getType()) 
                case "payment_intent.succeeded":
                    PaymentIntent paymentIntent = (PaymentIntent) stripeObject;
                    System.out.println("Payment succeeded for   "+paymentIntent.getAmount());
                    System.out.println("payload is : "+payload);
                    handlePaymentIntentSucceeded(paymentIntent);
                    // Then define and call a method to handle the successful payment intent.
                    break;
                default:
                    System.out.println("Unhandled event type: " + event.getType());
                    break;
            
            return "200";
    


    private void handlePaymentIntentSucceeded(PaymentIntent paymentIntent) 
        
        //do some stuff here    
    
    

【问题讨论】:

请描述正在加载的 URL 序列,从何处加载。例如,如果 webhook 控制器被 from Stripe 调用,而不是作为浏览器 redirect,那么它将永远无法访问用户的会话。 请在您的问题中添加Minimum Reproducible Example。 @dbreaux 我的 webhook 控制器是从条带中调用的,而不是作为 Bowser 重定向,所以没有任何方法可以获取相同的会话数据吗?请指导我。 【参考方案1】:

Webhook 在生成事件时作为完全独立的 POST requests 直接与 Stripe 的 webhook delivery servers 交付。您的客户不会以任何方式重定向到此,并且请求不会包含除事件对象之外的任何内容。

您无法像尝试从 webhook 事件中那样获取会话数据。

相反,您可以在创建 Payment Intent (API ref) 时设置 metadata,并且 metadata 将包含在任何 Payment Intent webhook 事件中。

【讨论】:

以上是关于重定向到条带后丢失会话数据的主要内容,如果未能解决你的问题,请参考以下文章

在 Codeigniter 中重定向后会话丢失

调用客户端重定向后会话属性丢失

使用 django python-social-auth 重定向后会话值丢失

OAuth 重定向后会话丢失

重定向后 ASP Net Core 2.2 会话丢失

是否可以在 Django 中重定向到没有 AJAX 的条带结帐页面?