代码之家  ›  专栏  ›  技术社区  ›  Martin Barth

perl6中使用Cro的基本身份验证

  •  9
  • Martin Barth  · 技术社区  · 7 年前

    401 Unauthorized 如果你不提供任何证件。如果你提供了错误的证件,我想看看 403 Forbidden

    在我的代码示例中,我从未看到 MyBasicAuth 正在调用的中间件:

    class MyUser does Cro::HTTP::Auth {
        has $.username;
    }
    
    subset LoggedInUser of MyUser where { .username.defined }
    
    class MyBasicAuth does Cro::HTTP::Auth::Basic[MyUser, "username"] {
        method authenticate(Str $user, Str $pass --> Bool) {
            # No, don't actually do this!
            say "authentication called";
            my $success = $user eq 'admin' && $pass eq 'secret';
            forbidden without $success;
            return $success
        }
    }
    
    sub routes() is export {
        my %storage;
        route {
            before MyBasicAuth.new;
            post -> LoggedInUser $user, 'api' {
                request-body -> %json-object {
                    my $uuid = UUID.new(:version(4));
                    %storage{$uuid} = %json-object;
                    created "api/$uuid", 'application/json', %json-object;
                }
            }
        }
    }
    
    2 回复  |  直到 7 年前
        1
  •  6
  •   Jonathan Worthington    7 年前

    这种结构:

    route {
        before MyBasicAuth.new;
        post -> LoggedInUser $user, 'api' {
            ...
        }
    }
    

    取决于新的 before after 即将发布的cro0.8.0中的语义。在当前的Cro发布中,在请求/编写时-以及之前的版本中- 之前 在一个 route

    route {
        before MyBasicAuth.new;
        delegate <*> => route {
            post -> LoggedInUser $user, 'api' {
                ...
            }
        }
    }
    

    它确保在考虑任何路由匹配之前应用中间件。这不是很好,因此在即将到来的0.8.0中的更改(它还将引入 before-matched 那是原版的 之前

    最后, forbidden without $success; forbidden sub是 Cro::HTTP::Router authenticate 方法是它返回一个真实值来决定应该发生什么;这不是一个合适的地方来尝试和强制不同的响应代码。

    无法匹配身份验证约束,如 LoggedInUser 将生成401。要重写它,请添加 之后 在最外面

    route {
        before MyBasicAuth.new;
        after { forbidden if response.status == 401; }
        delegate <*> => route {
            post -> LoggedInUser $user, 'api' {
                ...
            }
        }
    }
    
        2
  •  3
  •   Martin Barth    7 年前

    似乎目前有一个错误,在cro发布版本,这是已经固定在上游上 github . 在“perl6 IRC频道”的senaŧu kun的帮助下,我们使用了当前版本的 cro-http :

    $ git clone https://github.com/croservices/cro-http.git
    $ perl6 -Icro-http/lib example.p6
    

    curl 我终于看到了“身份验证调用”。

    这个 curl -v -d '{"string":"hi"}' http://admin:secret@localhost:10000/api 我忘了加 -H 'Content-Type: application/json'

    authentication called An operation first awaited:   in sub request-body at /home/martin/.workspace/voteimproved/cro-http/lib/Cro/HTTP/Router.pm6 (Cro::HTTP::Router) line 716   in block  at restapp/example.pl line 24 in block  at /home/martin/.workspace/voteimproved/cro-http/lib/Cro/HTTP/Router.pm6 (Cro::HTTP::Router) line 130
    
    Died with the exception:
        Cannot unbox a type object (Nil) to int.
          in sub decode-payload-to-pairs at /home/martin/.workspace/voteimproved/cro-http/lib/Cro/HTTP/BodyParsers.pm6 (Cro::HTTP::BodyParsers) line 62
          in method parse at /home/martin/.workspace/voteimproved/cro-http/lib/Cro/HTTP/BodyParsers.pm6 (Cro::HTTP::BodyParsers) line 50
          in method body at /home/martin/.rakudobrew/moar-2018.08/install/share/perl6/site/sources/557D6C932894CB1ADE0F83C0596851F9212C2A67 (Cro::MessageWithBody) line 77
          in sub request-body at /home/martin/.workspace/voteimproved/cro-http/lib/Cro/HTTP/Router.pm6 (Cro::HTTP::Router) line 716
          in block  at restapp/example.pl line 24
          in block  at /home/martin/.workspace/voteimproved/cro-http/lib/Cro/HTTP/Router.pm6 (Cro::HTTP::Router) line 130
    

    这个 第二 forbidden 在本部分中:

    class MyBasicAuth does Cro::HTTP::Auth::Basic[MyUser, "username"] {
        method authenticate(Str $user, Str $pass --> Bool) {
            say "authentication called";
            my $success = $user eq 'admin' && $pass eq 'secret';
            forbidden unless $success;
            return $success;
        } }
    

    authentication called
    Can only use 'content' inside of a request handler
      in sub set-status at /home/martin/.workspace/voteimproved/cro-http/lib/Cro/HTTP/Router.pm6 (Cro::HTTP::Router) line 846
      in sub forbidden at /home/martin/.workspace/voteimproved/cro-http/lib/Cro/HTTP/Router.pm6 (Cro::HTTP::Router) line 823
      in method authenticate at restapp/example.pl line 15
      in method process-auth at /home/martin/.workspace/voteimproved/cro-http/lib/Cro/HTTP/Auth/Basic.pm6 (Cro::HTTP::Auth::Basic) line 26
      in block  at /home/martin/.workspace/voteimproved/cro-http/lib/Cro/HTTP/Auth/Basic.pm6 (Cro::HTTP::Auth::Basic) line 11
      in block  at /home/martin/.workspace/voteimproved/cro-http/lib/Cro/HTTP/Auth/Basic.pm6 (Cro::HTTP::Auth::Basic) line 8
      in block  at /home/martin/.workspace/voteimproved/cro-http/lib/Cro/HTTP/Internal.pm6 (Cro::HTTP::Internal) line 22
      in block  at /home/martin/.workspace/voteimproved/cro-http/lib/Cro/HTTP/RequestParser.pm6 (Cro::HTTP::RequestParser) line 109
      in block  at /home/martin/.workspace/voteimproved/cro-http/lib/Cro/HTTP/RequestParser.pm6 (Cro::HTTP::RequestParser) line 90
      in block  at /home/martin/.rakudobrew/moar-2018.08/install/share/perl6/site/sources/F048BB66854D2463798A39CC2B01D4CC1532F957 (Cro::TCP) line 53
    

    我想这个问题很快就会解决的!

    推荐文章