PhpMyadmin 令牌认证系统

PhpMyadmin Token Authentification system

我最近有了一个想法,即使用存储在数据库中的登录凭据创建的令牌创建 PhpMyAdmin 的登录系统。 url 看起来像这样:

pma.example.com/index.php?token=WCxuFWj1QtGGapZhfSPS9Eo1Q9q666sR

令牌包含 32 个随机生成的字母数字字符。

所以我有一个 API 在 Python 中用 Flask 制作,它在本地与 PhpMyadmin 和不同的应用程序进行通信,它有两条路线:

  1. 127.0.0.1:4040/api/v1/create_token [POST] 此请求具有作为 JSON 参数 database_host_id 的 MySQL 主机 ID 以连接定义在 PhpMyAdmin 配置文件中,database_username 这是写入数据库用户连接,最后 database_host 这是数据库密码。响应有一个 token 参数供客户端接收新生成的令牌。 发送和接收的 JSON 应该是这样的:
JSON received by the API :
{
  "database_host_id": 1,
  "database_username": "pma",
  "database_password: "4wAyS8",
}

JSON sent to the client:
{
  "token": "WCxuFWj1QtGGapZhfSPS9Eo1Q9q666sR"
}
  1. 127.0.0.1:4040/api/v1/get_database [POST] 此请求有一个 JSON 参数 token 以了解从哪个令牌检索连接信息。因此响应将包含所有这些信息以及 database_host_iddatabase_usernamedatabase_password。发送和接收的 JSON 应该是这样的:
JSON received by the API :
{
  "token": "WCxuFWj1QtGGapZhfSPS9Eo1Q9q666sR"
}

JSON sent to the client :
{
  "database_host_id": 1,
  "database_username": "pma",
  "database_password: "4wAyS8",
}

有一个API很好,但是如果你不使用它,它就没用了,所以我在 PhpMyAdmin 的源代码中搜索了身份验证系统是如何工作的。

我能理解:

$auth_plugin = Plugins::getAuthPlugin();
$auth_plugin->authenticate();

所以现在我不得不修改 AuthenticationCookie.php 脚本,以便当 token 包含在 URL 中时,它可以从 API 中检索信息,然后使用它连接到与该令牌关联的数据库。

这就是我陷入困境的地方,因为尽管我有 PHP 基础知识,但我无法将我正在做的事情付诸实践。尽管我尝试过,但我注意到当我从 URL 检索令牌时,它根本不是定义的内容,就好像它是加密的。

所以这是我的问题:

  1. 即使 API 仅在本地通信,我是否应该加密密码?
  2. 我的 MySQL 主机不应该只使用 SignOn 连接方法吗?
  3. 做我想做的事情安全吗?

信息:

我将不胜感激任何帮助我推理或回答我的问题

我最终制作了一个与我的服务器关联的 SignOn 脚本,该脚本从 URL 获取令牌,向 API 询问令牌信息,然后与其连接。它完美运行。

<?php
/**
 * Single signon for phpMyAdmin
 *
 * This is just example how to use session based single signon with
 * phpMyAdmin, it is not intended to be perfect code and look, only
 * shows how you can integrate this functionality in your application.
 */

declare(strict_types=1);

/* Use cookies for session */

ini_set('session.use_cookies', 'true');
/* Change this to true if using phpMyAdmin over https */
$secure_cookie = false;
/* Need to have cookie visible from parent directory */
session_set_cookie_params(0, '/', '', $secure_cookie, true);
/* Create signon session */
$session_name = 'SignonSession';
session_name($session_name);
// Uncomment and change the following line to match your $cfg['SessionSavePath']
//session_save_path('/foobar');
@session_start();

/* Was data posted? */
if (isset($_REQUEST['token'])) {
    $data = array(
        'token'=> $_REQUEST['token']
    );
    $payload = json_encode($data);
    $curl = curl_init('http://127.0.0.1:4040/api/v1/get_database');
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $payload);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    $response = curl_exec($curl);

    curl_close($curl);

    $response = json_decode($response, true);
    
    /* Store there credentials */
    $_SESSION['PMA_single_signon_user'] = $response->database_username;
    $_SESSION['PMA_single_signon_password'] = $response->database_password;
    $_SESSION['PMA_single_signon_host'] = $_POST['host'];
    $_SESSION['PMA_single_signon_port'] = $_POST['port'];
    /* Update another field of server configuration */
    $_SESSION['PMA_single_signon_cfgupdate'] = ['verbose' => 'Signon test'];
    $_SESSION['PMA_single_signon_HMAC_secret'] = hash('sha1', uniqid(strval(rand()), true));
    $id = session_id();
    /* Close that session */
    @session_write_close();
    /* Redirect to phpMyAdmin (should use absolute URL here!) */
    header('Location: ../index.php');
} else {
    /* Show simple form */
    header('Content-Type: text/html; charset=utf-8');

    echo '<?xml version="1.0" encoding="utf-8"?>' . "\n";
    echo '<!DOCTYPE HTML>
<html lang="en" dir="ltr">
<head>
<link rel="icon" href="../favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="../favicon.ico" type="image/x-icon">
<meta charset="utf-8">
<title>Loading...</title>
</head>
<body>';

    if (isset($_SESSION['PMA_single_signon_error_message'])) {
        echo '<p class="error">';
        echo $_SESSION['PMA_single_signon_error_message'];
        echo '</p>';
    }

    echo '
<h1>Loading...</h1>
</body>
</html>';
}

我知道它还没有完成,但我打算改进它。所以这就是我找到的解决方案。