取势 明道 优术

作者为 扶 凯 发表

目前有大量的 Plack 中间件的应用,在 Plack 应用的核心发布包也中包含有一些,另外还有 CPAN 上有一些非常不错的应用.我写这个 advent calendar 就是为了让更多人了解和喜欢这些中间件.
从今天起,我们就为大家介绍其中一些非常非常好的中间件,您可以用来快速实现你的应用程序.

Basic authentication(基本的认证)

由于 Plack 中间件可以封装应用程序本身,可以很方便的进行应用前处理 pre-process 或 post-process 应用后处理的相关 HTTP 操作.今天我们来谈一下最常用的功能之一用户的身份认证的验证.
在应用中加入身份验证有几个方法,你可以在你的 web 应用框架那层来支持这个功能,象 Catalyst 他有 Catalyst::Authentication::Credential::HTTP 的模块来实现.其它东西也能配置认证的功能,有简单的,也有复杂的,也有能使用凭证(验证方式:基本认证或摘要认证)和存储(如何保管授权的用户名和密码).
正常的时候,我们所能想到的是,你能在你的 web 服务器层来完成这个功能.如果你是使用的 Apache 的 mod_perl 来运行你的应用,你就可以使用 Apache 的 mod_auth 的模块来实现用户认证的功能.但这还只能是有限的功能.要想要实现复杂的认证:比如通过 database 中的信息来认证用户,就需要自己来写模块实现了.
Plack 中间件允许 Web 应用程序框架共享这样的功能,大多是一个非常简单的 Perl 回调,这样实现起来就容易多了, 比如 Plack::Middleware::Auth::Basic 在这只完成基本的身份验证.
这样就是为什么大多数 Plack 后端服务器都没有一个认证系统的原因,因为只要使用中间件组件就能统一实现了.

使用 Plack::Middleware::Auth::Basic
象其它的中间件,使用 Auth::Basic 也是简单又快速的.

use Plack::Builder;

my $app = sub { ... };

builder {
    enable "Auth::Basic", authenticator => sub {
        my($username, $password) = @_;
        return $username eq 'admin' && $password eq 'foobar';
    };
    $app;
};

象上面这样,就封装加入了一个基本的认证在你的 $app 的应用中,使用用户名叫 admin 和使用密码为 foobar .如果正常的登陆进入通过认证,就可以通过 PSGI 中的 $env 环境变量取得 REMOTE_USER 的变量中的用户名.
这是基于回调的应用,象要增加其它的认证的方法,如 Kerberos ,只需要使用 Authen::Simple 就行.

use Plack::Builder;
use Authen::Simple;
use Authen::Simple::Kerberos;

my $auth = Authen::Simple->new(
    Authen::Simple::Kerberos->new(realm => ...),
);

builder {
    enable "Auth::Basic", authenticator => sub {
        $auth->authenticate(@_):
    };
    $app;
};

我们可以见到,使用了这个 Authen::Simple 来做后端服务的认证,也只需要很小的改变就能实现.


当使用了 URLMap 时怎么办?
URLMap 可以混合多个应用成一个应用,我们可以绑定认证的中间件到其中一个应用.是否使用和不使用认证相当灵活,只需要在认证部分有少量的不同,如下:

use Plack::Builder;
my $app = sub {
    my $env = shift;
    if ($env->{REMOTE_USER}) { 
        # Authenticated
    } else {
        # Unauthenticated
    }
};

builder {
    mount "/private" => builder {
        enable "Auth::Basic", authenticator => ...;
        $app;
    };
    mount "/public" => $app;
};

这时,你打开相同的应用 $app ,只要通过不同的路径 "/public" 和 "/private" 就行.这时打开 /private 会需要认证.才能取得 $env->{REMOTE_USER}. 实际可能我们会复杂一些.

 这是我的译文,原文地址:http://advent.plackperl.org/2009/12/day-15-authenticate-your-app-with-middleware.html

 

来了就留个评论吧! 1个评论