我在Ionic框架内遇到Braintree dropin UI的一种非常奇怪的行为。
所以我使用解决方案:Can't create Braintree client token with customer ID 第一次创建逻辑和返回客户。
$http({
method: 'POST',
url: 'http://localhost:3000/api/v1/token',
data: {
customerId: braintreeReturnCustomerId
}
})
当我在客户端视图中传入customerId时。在我的nodejs服务器中,我有一个逻辑来检查customerId是否未定义。如果未定义,则是第一次客户。如果customerId有价值,则返回客户。非常直接,如此:
app.post('/api/v1/token', jsonParser, function (request, response) {
var customerId = request.body.customerId;
if (customerId == undefined) {
gateway.clientToken.generate({}, function (err, res) {
if (err) throw err;
response.json({
"client_token": res.clientToken
});
});
} else {
console.log ("using exsiting customer!");
gateway.clientToken.generate({
customerId: customerId
}, function (err, res) {
if (err) throw err;
response.json({
"client_token": res.clientToken
});
});
}
});
我的客户处于离子视图中。因此,当我第一次付款时,它知道用户是第一次,然后为我生成customerId并将其存储在我的数据库中。都好。然后没有刷新(因为当状态改变时Ionic应用程序不刷新),我进入不同的状态并返回到支付状态,它不显示商店信用卡。甚至我的服务器都记录了customerId,我知道服务器代码正在使用gateway.clientToken.generate运行“else”部分({customerId:customerId} ...
如果我在视图中强制刷新,比如使用
$window.location.reload(true);
第一次付款成功后,或者我只是在我的Chrome浏览器中手动刷新页面(因为我在Ionic Serve中),付款Dropin UI页面将显示第一次付款时的商店信用卡。
我尝试禁用视图缓存,例如“cache:false”。但它没有帮助。我必须强制刷新才能使Dropin UI第二次运行。我认为这是dropin UI中的javascript代码导致此问题,但我不知道如何解决它...
答案 0 :(得分:4)
完全披露:我在Braintree工作。如果您有任何其他问题,请随时联系support。
您发布的方法极不安全,因为它容易受到Insecure Direct Object Reference(OWASP Top 10)的攻击,并且很容易导致恶意用户进行跨用户收费。您基本上允许任何用户使用您的服务器为任何客户生成客户端令牌。
相反,您应该只在服务器上生成令牌,以避免用户代理选择其他用户的ID。然后根据用户的凭证登录提供客户ID,并且不允许他们传递在clientToken生成期间使用的参数。有many guides online on how to build authentication。但是,一旦在服务器上创建了用户,您就可以:
if (userSession == undefined) {
//or force login if you want them to sign up for your site before buying things
gateway.clientToken.generate({}, function (err, res) {
if (err) throw err;
response.json({
"client_token": res.clientToken
});
});
} else {
console.log ("using exsiting customer!");
gateway.clientToken.generate({
customerId: userSession.user.BraintreeId
}, function (err, res) {
if (err) throw err;
response.json({
"client_token": res.clientToken
});
});
}
无论你做什么,都不要在生产中使用这段代码。在重建修复此漏洞之前,我不会建议调试前端,因为方法会有很大不同。但是,如果您再次回到此问题,则可能会显示an open issue related this behavior。