1

有没有办法像这样访问sessionMojolicious::Lite 中的 websocket 请求?

get '/' => sub {
  my $self = shift;
  $self->session->{foo} = 'bar';
  $self->render('index');
};

websocket '/ws' => sub {
  my $self = shift;
  $self->on(message =>
    sub {
      my ($self, $msg) = @_;
      my $foo = $self->session->{foo}; # <<<<< is actually empty
    }
  );
};

有什么提示吗?

4

1 回答 1

0

我最终将签名的 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...
        }
      );
于 2012-10-11T09:47:56.407 回答