使用PDO身份验证器,Slim 3的HTTP基本身份验证失败

I am using Slim v 3 with JWT for writing REST APIs. I followed https://github.com/tuupola/slim-jwt-auth and it is working fine.

I am generating a token each time the user logs into the appl. To authenticate the user, I followed https://github.com/tuupola/slim-basic-auth to use as auth middleware. On success, I am generating a token using https://github.com/firebase/php-jwt.

I was going through a related question on SO here, JWT: Authentication in slim v3 and Android and I have a query on http basic auth. (I dont have sufficient rep to make a comment there ).

Now my questions:

  1. HttpBasicAuthentication through the 'users' option is working fine but I wouldnt be able to use it against my users table obviously. Many users would be logging into the application and listing all of them in the 'users' is not an option. Am I right here?

  2. If yes, I have to use Pdo Authenticator. I configured it but authentication is failing and I couldnt solve it. The error callback is being fired with "Authentication failed" message. My database has 'users' table with 'user' and 'hash' columns for username and password. Below is the piece of code I am using.

use Slim\Middleware\HttpBasicAuthentication;
use Slim\Middleware\HttpBasicAuthentication\PdoAuthenticator;
$pdo = new \PDO('mysql:host=localhost;dbname=test', $dbUser, $dbPassword);

$middlewareHttpBasicAuthConfig = [
        /*"users" => [
            "user1" => "password"
        "secure" => false,
        "relaxed" => ["localhost", "amruta-pani"],
        "path" => "/*",
        "passthrough" => Utils::httpAuthPassThroughRoutes,
        "realm" => "Protected",

        "authenticator" => new PdoAuthenticator([
            "pdo" => $pdo

        "callback" => function($request, $response, $arguments) {
            echo "Through<br>

        "error" => function($request, $response, $arguments) {
            echo "Failed<br>

    $app->add(new HttpBasicAuthentication($middlewareHttpBasicAuthConfig));

I am using Google Advanced Rest Client for testing it and the output I am seeing is

    [message] => Authentication failed

I have added below rule to my Apache webserver

RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

What am I missing here?

duanguanzai6181 是的哈希密码。如果您想使用明文密码,您必须按照Werner的建议编写自己的验证器。
大约 4 年之前 回复
douji9734 这不是我将以纯文本形式存储密码,而是在测试时禁用了散列模块。pdo身份验证器是否仅适用于哈希密码?
大约 4 年之前 回复
dsoy71058 是。绝对不应该在数据库中存储明文密码。
大约 4 年之前 回复
dopgv00024 谢谢,它在我输入密码时起作用了。但是密码哈希是强制性的吗?
大约 4 年之前 回复
douhuai4155 是的我可以连接到数据库。但是当我测试它时,我没有对密码进行哈希处理。是否需要哈希?
大约 4 年之前 回复
doukekui0914 你能连接数据库吗?你是如何将用户插入数据库的,即你是否在将密码插入数据库之前对其进行哈希处理?
大约 4 年之前 回复
dongluolie3487 我跟着他们两个:github.com/tuupola/slim-basic-auth#usage-with-pdo,appelsiini.net/2014/slim-database-basic-authentication。第二个是关于PDO的详细信息
大约 4 年之前 回复
dt3674 您可以添加您正在使用的PDP身份验证的链接吗?
大约 4 年之前 回复


@Mika Tuupola帮助我在评论中解决了这个问题并且归功于他,我认为这会对某人有所帮助。 我希望他能回答这个标记。</ p>

无法使用PDO驱动程序验证密码文本密码,但是,如果 配置数组具有'users'属性,如下所示具有明文密码,将在生产中显然不会出现这种情况。</ p>

  $ app-&gt; add(new 
ew Slim \ Middleware \ HttpBasicAuthentication([
“users”=&gt; [
</ code> </ pre>

https://上的GitHub文档 github.com/tuupola/slim-basic-auth 非常适合使用这个中间件但是当它提到明文密码时,引用 - </ p>

Cleartext 密码仅适用于快速测试。 你可能...... </ p>
</ blockquote>

我用PDO用明文密码对它进行测试,直到密码被散列后才能正常工作。</ p>
< / DIV>



@Mika Tuupola helped me resolve this problem in the comments and credit goes to him, and I thought it would help somebody. I was hoping that he would answer it for me to mark it.

Passwords should be hashed for HTTPBasicAuthentication middleware to work. Clear text passwords cannot be authenticated with PDO driver, however, if the configuration array has 'users' property, with a clear text password like below, will work which obviously wouldnt be the case in production.

$app->add(new \Slim\Middleware\HttpBasicAuthentication([
    "users" => [
        "root" => "t00r",
        "somebody" => "passw0rd"

The GitHub documentation at https://github.com/tuupola/slim-basic-auth was good enough to use this middleware however when it mentioned about clear text passwords, quote -

Cleartext passwords are only good for quick testing. You probably...

I went ahead testing it with clear text passwords with PDO and it didnt work till the password is hashed.

您似乎需要将数据库命名方案传递给PdoAuthenticator,如博客文章。</ p>

在您的情况下,这将是...... < / p>

 “authenticator”=&gt; 新的PdoAuthenticator([
“pdo”=&gt; $ pdo,

</ code> </ pre>

...这似乎是默认值。 由于简单的底层PDO连接问题,它可能无法正常工作。 另外,查看来源</ a >,PdoAuthenticator在内部使用password_verify(),因此它只能在PHP 5&gt; = 5.5.0和PHP 7中使用。</ p>

您也可以使用自己的身份验证器。 至于你在自己的验证器回调中处理凭证的问题,你可以这样做:</ p>

  class MyAuthenticator实现AuthenticatorInterface {
public function __invoke(array $ arguments) ){
// $ arguments ['user']将包含用户名
// $ arguments ['password']将包含密码
</ code > </ pre>
</ div>



It seems you need to pass your database naming scheme to the PdoAuthenticator as described in the blog post.

In your case this would be something like...

"authenticator" => new PdoAuthenticator([
    "pdo" => $pdo,
    "table" => "users",
    "user" => "user",
    "hash" => "hash"

...which indeed seem to be the default values. Maybe it's not working due to a simple underlying PDO connection problem. Also, looking at the source, the PdoAuthenticator uses password_verify() internally, so it will only be available in PHP 5 >= 5.5.0 and PHP 7.

You could also roll your own authenticator. As far as your question about handling the credentials in your own authenticator callback goes, you would do something like:

class MyAuthenticator implements AuthenticatorInterface {
    public function __invoke(array $arguments) {
        // $arguments['user'] will contain username
        // $arguments['password'] will contain password
        // Do stuff...

dongzi1397 您只需要传递表名和/或列,您使用的是默认值以外的其他内容。 中间件的PHP要求为^ 5.5 || ^ 7.0因此,如果操作系统使用PHP 5.4,则甚至不会安装。
大约 4 年之前 回复
douping1581 让我们在聊天中继续讨论。
大约 4 年之前 回复
dongluan1901 查看源代码,PdoAuthenticator通过password_verify()验证密码。 您使用的是PHP 5> = 5.5.0还是PHP 7? 我建议您编写自己的身份验证器作为快速测试。
大约 4 年之前 回复
douzhanlai4671 不过,我无法理解输出中的额外[0] =>用户,[1] =>密码
大约 4 年之前 回复
doushao6874 上面的代码片段给出了这个输出:Array([user] => user [0] => user [hash] => password [1] => password)失败<br> Array([message] =>身份验证失败)
大约 4 年之前 回复
dongzan1970 不,它没有用。 我添加了下面的代码片段来检查连接。 尝试{$ pdo = new \ PDO('mysql:host = localhost; dbname = test',$ dbUser,$ dbPassword); foreach($ pdo-> query('SELECT user,hash from users')as $ row){print_r($ row); catch(PDOException $ e){print“错误!:”。 $ e-> getMessage()。 “<BR/>”; 死(); }
大约 4 年之前 回复
dormbaf90464 查看源代码,情况似乎如此 - 您使用了默认值。 使用array_merge()在内部应用不同的值:github.com/tuupola/slim-basic-auth/blob/2.x/src/ ... 为什么不调试authenticator的__invoke()方法呢? 可能就像PDO连接问题一样简单吗?
大约 4 年之前 回复
douben6670 我是否需要明确提及表,用户,哈希值? 我将它们理解为默认值,所以我跳过它们。 让我尝试
大约 4 年之前 回复
duanao4729 我在你的案例中使用提供的PdoAuthenticator的例子更新了我的答案,因为你不打算编写自己的身份验证器。
大约 4 年之前 回复
dongxiusuo9881 顺便说一下,这条线的意思是返回(bool)rand(0,1); ? 这是我们需要验证凭据的地方吗?
大约 4 年之前 回复
dongzhi8487 是。 我确实经历过这个,但是一旦我完成了Pdo Authenticator,我就想测试/使用它。 自定义身份验证可能是我的要求的理想解决方案,但尽管如此我手头还有一个未解决的问题。
大约 4 年之前 回复