我最终将签名的 cookie 值存储在隐藏的 div 中,然后将其与每个 WS 消息一起作为“协议”的一部分发送。在消息处理程序中,我检查 cookie 值是否存在,检查它的签名,然后 base64-decode 并像往常一样使用它,如下所示:
sub decode_cookie {
my ($self, $cookie_val) = @_;
my $json = Mojo::JSON->new();
my $secret = $self->stash->{'mojo.secret'};
if ($cookie_val =~ s/--([^\-]+)$//) {
my $sig = $1;
#app->log->debug("cookie=".$cookie_val);
#app->log->debug("sig=".$sig);
my $check = Mojo::Util::hmac_sha1_sum $cookie_val, $secret;
unless(Mojo::Util::secure_compare $sig, $check) {
app->log->warn("invalid session cookie signature");
return;
}
} else {
app->log->warn("failed to extract cookie value");
return;
}
my $session = $json->decode(Mojo::Util::b64_decode($cookie_val));
unless($session) {
app->log->warn("failed to b64-decode session cookie");
return;
}
return $session;
}
websocket '/rtc' => sub {
my $self = shift;
my $json = Mojo::JSON->new;
$self->on(message =>
sub {
my ($self, $data) = @_;
app->log->debug("received WS message: ".$data);
$data = $json->decode($data);
my $session = decode_cookie($self, $data->{cval});
# do whatever you have to here...
}
);