将 Perl 数据结构作为序列化 GET 字符串传递给 Perl CGI 程序

发布于 2024-08-12 16:47:27 字数 354 浏览 3 评论 0原文

我想将序列化的 Perl 数据结构作为 GET 变量传递给 CGI 应用程序。我尝试 Data::Serializer 作为我的第一个选择。不幸的是,除了包含由“^”(插入符号)连接的选项之外,序列化的字符串对于我来说太长了。

有没有一种方法可以从 perl 数据结构创建短编码字符串,以便我可以安全地将它们作为 GET 变量传递到 perl CGI 应用程序?

我也很高兴被告知,这是将复杂数据结构传递到 Web 应用程序的糟糕方法(序列化、编码字符串),以及有关如何实现此目标的建议

I want to pass a serialized Perl data structure as a GET variable to a CGI application. I tried Data::Serializer as my first option. Unfortunately the serialized string is too long for my comfort, in addition to containing options joined by '^' (a caret).

Is there a way I can create short encoded strings from perl data structures so that I can safely pass them as GET variables to a perl CGI application?

I would also appreciate being told that this (serialized, encoded strings) is a bad way to pass complex data structures to web applications and suggestions on how I could accomplish this

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

失与倦" 2024-08-19 16:47:28

传递序列化编码字符串是将复杂数据结构传递给 Web 应用程序的糟糕方法。

如果您尝试在页面之间传递状态,可以使用服务器端 会话 这只需要您传递会话密钥。

如果您需要通过电子邮件将链接发送给某人,您仍然可以创建一个具有合理到期时间的服务器端会话(您还需要决定是否需要额外的身份验证),然后在链接中发送会话 ID。一旦采取请求的操作,您可以/应该立即使会话过期。

Passing serialized encoded strings is a bad way to pass complex data structures to web applications.

If you are trying to pass state from page to page, you can use server side sessions which would only require you to pass around a session key.

If you need to email a link to someone, you can still create a server-side session with a reasonable expiry time (you'll also need to decide if additional authentication is necessary) and then send the session id in the link. You can/should expire the session immediately once the requested action is taken.

旧城空念 2024-08-19 16:47:27

如果您需要向用户发送包含一些关键数据点的 URL,并且希望确保它不会被伪造,您可以使用摘要(例如来自 Digest::SHA)和共享密钥来完成此操作。这使您可以将数据放在消息中,而无需保留本地数据库来跟踪所有数据。我的示例不包含时间元素,但如果您愿意,添加时间元素也很容易。

use Digest::SHA qw(sha1_base64);
my $base_url = 'http://example.com/thing.cgi';

my $email = '[email protected]';
my $msg_id = '123411';

my $secret = 'mysecret';
my $data = join(":", $email, $msg_id, $secret);
my $digest = sha1_base64($data);

my $url = $base_url . '?email=' . $email . '&msg_id=' . $msg_id' . '&sign=' . $digest;

然后一起发送。

在“thing.cgi”脚本中,您只需要提取参数并查看脚本中提交的摘要是否与您本地重新生成的摘要匹配(使用 $email 和 $msg_id,当然还有您的 $secret)。如果它们不匹配,请不要授权它们,如果它们匹配,那么您就有合法授权的请求。

脚注:
我将“原始”方法写入 Data::Serializer 中,以使序列化器之间的转换变得更加容易,实际上这确实有助于(在某种程度上)在语言之间进行转换。但这当然是一个单独的讨论,因为您真的不应该使用序列化器在 Web 表单上交换数据。

If you need to send URL's to your users that contains a few key datapoints and you want to ensure it can't be forged you can do this with a Digest (such as from Digest::SHA) and a shared secret. This lets you put the data out there in your messages without needing to keep a local database to track it all. My example doesn't include a time element, but that would be easy enough to add in if you want.

use Digest::SHA qw(sha1_base64);
my $base_url = 'http://example.com/thing.cgi';

my $email = '[email protected]';
my $msg_id = '123411';

my $secret = 'mysecret';
my $data = join(":", $email, $msg_id, $secret);
my $digest = sha1_base64($data);

my $url = $base_url . '?email=' . $email . '&msg_id=' . $msg_id' . '&sign=' . $digest;

Then send it along.

In your "thing.cgi" script you just need to extract the parameters and see if the digest submitted in the script matches the one you locally regenerate (using $email and $msg_id, and of course your $secret). If they don't match, don't authorize them, if they do then you have a legitimately authorized request.

Footnote:
I wrote the "raw" methods into Data::Serializer to make translating between serializers much easier and that in fact does help with going between languages (to a point). But that of course is a separate discussion as you really shouldn't ever use a serializer for exchanging data on a web form.

冧九 2024-08-19 16:47:27

该方法的缺点之一(即使用特定于 Perl 的序列化程序)是,如果您想使用 Perl 以外的其他方式在客户端和服务器之间进行通信,那么它可能比 JSON 甚至 XML 等方式需要更多工作。是。您已经遇到过 GET 请求的大小限制,但这对于任何编码方案都是有问题的。

与您相比,这更有可能成为下一个维护此代码的人的问题。我现在遇到的情况是,在我之前从事大型系统工作的开发人员决定将几个重要的数据存储为 perl Storable 对象。这本身并不是一个可怕的决定,但它使使用不是用 perl 编写的工具访问数据变得更加困难。

One of the drawbacks of the approach — using a perl-specific serializer, that is — is that if you ever want to communicate between the client and server using something other than perl it will probably be more work than something like JSON or even XML would be. The size limitations of GET requests you've already run in to, but that's problematic for any encoding scheme.

It's more likely to be a problem for the next guy down the road who maintains this code than it is for you. I have a situation now where a developer who worked on a large system before I did decided to store several important bits of data as perl Storable objects. Not a horrible decision in and of itself, but it's making it more difficult than it should be to access the data with tools that aren't written in perl.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文