Mojolicious初学(八)

一、Under——条件中间件

我们见过很多网站,打开网址时是一个登录框。无论是我们怎么样输入网址,总会跳转到登录界面,除非我们输入账户名密码登录。

under中间件为我们实现了这种功能。设置under后,我们在其后开发的url方法,被浏览器发送的网址访问时,Mojolicious会首先调用under中间件定义的方法。如果返回为真,将继续访问至url指向的方法,如果为假,将停止下面的访问。

看一个例子:

use Mojolicious::Lite -signatures;

# under方法验证name参数是否等于‘Bender’
under sub ($c) {

  # 这是一个简单的模拟登录认证的方法,如果等于Bender返回1
  my $name = $c->param('name') || '';
  return 1 if $name eq 'Bender';

  # 如果不等于,相当于未认证,将会跳转到denied.html,并返回undef,即假
  $c->render(template => 'denied');
  return undef;
};

# 只有认证了才能访问index.html
get '/' => 'index';

app->start;
__DATA__

@@ denied.html.ep
You are not Bender, permission denied.

@@ index.html.ep
Hi Bender.

under关键字有一个参数,作为路由的前缀:

use Mojolicious::Lite;

# /foo
under '/foo';                                    # under中间件定义了一个/foo前缀。这将影响到后面所有的route方法——/bar和/baz

# /foo/bar
get '/bar' => {text => 'foo bar'};

# /foo/baz
get '/baz' => {text => 'foo baz'};

# / (reset)
under '/' => {msg => 'whatever'};               # 通过under中间件重新定义为/,取消了/foo前缀。

# /bar
get '/bar' => {inline => '<%= $msg %> works'};

app->start;

under中间件可以借助group关键字进行多层嵌套,即在under下嵌套一个under:

use Mojolicious::Lite -signatures;

# 这是一个全局的under,将作用于下面所有的路由
under sub ($c) {
  return 1 if $c->req->headers->header('X-Bender');
  $c->render(text => "You're not Bender.");
  return undef;
};

# 这里调用了group,形成了/admin节
group {

  # 此处的under中间件仅仅作用在group域内
  under '/admin' => sub ($c) {
    return 1 if $c->req->headers->header('X-Awesome');
    $c->render(text => "You're not awesome enough.");
    return undef;
  };

  # GET /admin/dashboard
  get '/dashboard' => {text => 'Nothing to see here yet.'};
};

# GET /welcome #仅受全under中间件,也就是第一个under的影响
get '/welcome' => {text => 'Hi Bender.'};

app->start;

标签