使用 Dancer 和 Postgres 的简单 Login/Authorization 系统

A Simple Login/Authorization system using Dancer and Postgres

作为 Perl 的新手,我正在努力寻找一种简单的方法来执行此操作。我在我的数据库中创建了一个非常简单的 table:

CREATE TABLE users (
id SERIAL NOT NULL PRIMARY KEY, 
username TEXT NOT NULL, 
password TEXT NOT NULL);

到目前为止,我使用了一个简单的登录系统,该系统具有我在网上找到的硬编码用户名和密码:

package Example;
use Dancer ':syntax';

our $VERSION = '0.1';
set session => "Simple";

get '/' => sub {
    # template 'index',{},{layout => 0};
    template 'index';
};

before sub {
    if (! session('user') && request->path_info !~ m{^/login}) {
        var requested_path => request->path_info;
        request->path_info('/login');
    }
};

get '/login' => sub {
    # Display a login page; the original URL they requested is available as
    # vars->{requested_path}, so could be put in a hidden field in the form
    template 'login', { path => vars->{requested_path} }, {layout => 0};
};

post '/login' => sub {
    # Validate the username and password they supplied
    if (params->{user} eq 'user' && params->{pass} eq 'letmein') {
        session user => params->{user};
        redirect params->{path} || '/';
    } else {
        redirect printf 'login failed';
    }
};

get '/logout' => sub {
  session->destroy;
  redirect '/';
};

如何开始链接数据库,然后将用户输入的内容与数据库中的内容进行匹配?还有我什么时候实施密码散列?任何教程将不胜感激 - 我一直在使用 metacpan,但它没有提供我需要的那么多细节!

最简单的方法: Dancer::Plugin::Authorize::Credentials::PostgreSQL

这里有一篇很好的文章,说明了如何正确地做到这一点:http://perlmaven.com/storing-passwords-in-a-an-easy-but-secure-way

post '/login' => sub {
    # Validate the username and password they supplied

    if (!params->{user} or !params->{pass}){ 
       redirect printf 'login failed';
    }
    # use your own encryption
    my $auth = auth($login, encrypt($password));
    # login successful
    if ($auth) {
        session user => params->{user};
        redirect params->{path} || '/';
    } else {
        redirect printf 'login failed';
    }
};

此致, 安德拉斯

Dancer::Plugin::Auth::Extensible 为您处理了很多样板代码。您可以建立一个简单的登录系统并 运行 而无需编写任何您自己的 /login 路由,如下所示。

配置Dancer::Plugin::Auth::Extensible

安装 Dancer::Plugin::Database and Dancer::Plugin::Auth::Extensible::Provider::Database 并将其添加到 config.yml:

session: "YAML"

plugins:
  Auth::Extensible:
    realms:
      users:
        provider: 'Database'
        disable_roles: 1

配置数据库连接

environments/development.yml 中配置您的数据库连接,以便您可以为开发和生产配置不同的配置。这是 MySQL 的配置,连接凭据(数据库名称、主机、用户名和密码)存储在单独的选项文件 database.cfg:

plugins:
  Database:
    dsn: 'dbi:mysql:;mysql_read_default_file=/path/to/database.cfg'
    dbi_params:
      RaiseError: 1
      AutoCommit: 1

对于 Postgres,您应该使用 .pgpass file to store your connection credentials. Make sure the file is not world readable. See this Stack Overflow post 作为示例。测试您的凭据文件是否可以在命令行上运行以及您的网络服务器是否可以读取它。

您现有的 table 似乎符合 suggested schema in the docs, but even if it doesn't, you can adjust the table and column names in the configuration

锁定你的路线

require_login 关键字添加到要保护的路由。 /login 路由将自动生成一个基本的登录表单,但如果您愿意,也可以 create your own

lib/MyApp.pm

package MyApp;
use Dancer ':syntax';

use Dancer::Plugin::Auth::Extensible;

our $VERSION = '0.1';

get '/' => require_login sub {
    template 'index';
};

true;

(是的,这确实是您必须编写的所有代码。我告诉过您它会处理很多样板文件。)

Crypt::SaltedHash 用于自动散列密码。请注意,永远不要在数据库中存储明文密码;当您将用户添加到您的数据库时,您应该生成密码的哈希值并存储该哈希值。

请注意,此示例中禁用了角色。如果您启用角色,您可以 do other nifty things 只允许具有管理员角色的用户查看管理页面。