如何强制登录并在Catalyst中拥有404页面?

时间:2014-02-08 13:59:42

标签: perl catalyst

我目前正在Root.pm中使用自动例程来强制登录。我现在需要404任何无效的网址,并仅检查有效网页的登录状态。

例如mysite.com/test_controller/action1应将新用户重定向到mysite.com/login(目前正在进行)。但是mysite.com/test_controller/typo_page应该返回404错误。

我知道我可以为每个控制器的每个动作设置一个基础来强制在动作级别进行登录,但是我希望有一种更简单的方法,我只是没有正确搜索。

有没有办法验证自动中的网址?

3 个答案:

答案 0 :(得分:2)

实施404的正确操作是在 Root 控制器中使用default。如果您使用标准Catalyst帮助程序创建应用程序,那将是标准。

sub default :Path {
    my ( $self, $c ) = @_;
    $c->response->body( 'Page not found' );
    $c->response->status(404);
}

Root 控制器中,这种情况的行为是当控制器的所有中的所有其他操作无法匹配时Root中的default将用作操作。不匹配任何是找不到页面的定义:404。

您可能遗漏的一点是autobeginend等其他操作一样,只有在路径匹配时才会执行调度执行 。因此,default作为每个控制器/路由的位置存在,以执行默认操作,其中不匹配。重点是,在您的上下文中,您并不是要求某人授权只是告诉他们URI不存在。

我在这里以简略的形式进行讨论以获得更多阅读,请参阅“Catalyst手册”文档中有关Built-in special actions的部分。

这就是您想要的,并且与您的控制器中的auto没有冲突。

既然你说这就是你所拥有的,那么你的代码就会出现问题。按照我的删节最小设置,找到适用的方法并将其与您的代码进行比较。

主要背景

你应该使用Catalyst :: Plugin :: Authentication,它经过了很好的测试和稳定。在你的主要上下文课中,你应该至少有这个。

use Catalyst qw/
    Authentication
/;

这需要一些配置,所以我们在这个类的 config 部分给它一些值

__PACKAGE__->config(

    'Plugin::Authentication' =>
    {
      default => {
          credential => {
              class => 'Password',
              password_field => 'password',
              password_type => 'clear'
          },

          store => {
              class => 'Minimal',
              users => {
                  guest => {
                      password => 'password',
                  }
              }
          }
      }
    }
);

Root控制器需要autodefault两个操作。第一个将执行身份验证检查,default将处理不匹配的任何内容。为了完整性而留下基本索引操作注意,当请求登录 URI时,我们会单独留下请求,或者通过返回 true来验证用户来自这个子。

sub auto :Private {
  my ( $self, $c ) = @_;

  if ( $c->request->path =~ /login/ ) {
    return 1;
  }

  if (!$c->user_exists) {

    $c->log->debug('**Root::auto User not found, forwarding to /login');

    $c->response->redirect( $c->uri_for('/login'));

  }

  return 1;

}

sub index :Path :Args(0) {
    my ($self, $c) = @_;
    $c->response->body( $c->welcome_message );
}

sub default :Path {
    my ( $self, $c ) = @_;
    $c->response->body( 'Page not found' );
    $c->response->status(404);
}

登录

在单独的控制器(在本例中为Login)中,定义登录注销操作。在此示例中,我们不会进行身份验证,只是证明default操作有效并且匹配仍然有效。所以两个简单的行动。

sub login :Path :Args(0) {
  my ( $self, $c ) = @_;

  $c->response->body('Matched AuthTest::Controller::Login in Login.');
}

sub logout :Path(/logout) :Args(0) {
  my ( $self, $c ) = @_;

  $c->logout;

  $c->res->redirect( $c->uri_for('/') );

}

运行应用程序和测试

您现在可以启动该应用程序。您现在应该在上下文类中设置-Debug或在环境中设置CATALYST_DEBUG=1。从类似的东西开始:

CATALYST_DEBUG=1 plackup -I lib

用卷曲测试

$ curl -I http://localhost:5000
HTTP/1.0 302 Found
Date: Sun, 09 Feb 2014 20:38:08 GMT
Server: HTTP::Server::PSGI
Location: http://localhost:5000/login
Content-Length: 5483
Content-Type: text/html; charset=utf-8
X-Catalyst: 5.90052

$ curl -I http://localhost:5000/blort
HTTP/1.0 404 Not Found
Date: Sun, 09 Feb 2014 20:40:12 GMT
Server: HTTP::Server::PSGI
Location: http://localhost:5000/login
Content-Length: 14
Content-Type: text/html; charset=utf-8
X-Catalyst: 5.90052

$ curl -I http://localhost:5000/logout
HTTP/1.0 302 Found
Date: Sun, 09 Feb 2014 20:40:48 GMT
Server: HTTP::Server::PSGI
Location: http://localhost:5000/
Content-Length: 301
Content-Type: text/html; charset=utf-8
X-Catalyst: 5.90052

要在浏览器中进行完整的完整性测试,请遵循发布的任何其他重定向。

可以在Catalyst Manual Section中找到更完整的示例,其中包含Authentication Plugin的更多信息。

答案 1 :(得分:0)

您可以看到this模块Catalyst :: Plugin :: Authorization :: ACL。 使用它可以配置允许和拒绝的URL路径,具体取决于是否记录的用户。

答案 2 :(得分:0)

我不确定这是否与您的意思和想要的一致,但如果我理解正确,请尝试以下方法:

# Root.pm
sub auto :Private {
    ...
    $c->detach('unmatchedURLs') if ( $c->action eq 'unmatchedURLs' ); # chose a more appropiate name if you need
    # do whatever you need to do with your registered URLs
    ...
}

sub unmatchedURLs :Path {
    my ( $self, $c ) = @_;

    $c->response->body('Page not found');
    $c->response->status(404);
    # or maybe doing something else for wrong URLs
}