1

我正在开发一个 3rd 方应用程序,我需要进行独立的登录身份验证。我不想设置会话或创建任何本地数据变量,我只想检查用户名/密码是否匹配。存在的问题是 XF 身份验证系统对我来说没有多大意义。我浏览了 XF 官方网站,但我没有收集到太多信息。我知道密码/盐数据存储在xf_user_authentication表中,但我不知道该怎么做。谁能向我解释一下密码是如何形成的,以及这张表中的内容是什么?

4

1 回答 1

0

为将来遇到此问题的任何人发布此答案。

XenForo 将用户密码存储在 中xf_user_authenticate,但没有用户名,仅user_id用于确定用户。用户名存储在xf_user. 为了比较用户名和密码,您需要SELECT user_id FROM xf_user WHERE username LIKE ...并使用您需要的SELECT data FROM xf_user_authenticate WHERE user_id LIKE ...,然后只需使用password_verify();将经过清理的用户输入与存储在数据库中的散列密码进行比较。请注意,散列密码与用于散列它们的成本和盐值一起存储在 .bin blob 中,这些是 的默认值password_verify();,因此在比较之前您真正需要做的就是剥离其余的使用$password = substr($password, 22, -3);($password是来自数据库的字符串),因为散列密码在 22 个字符后开始,末尾有 3 个尾随字符,散列长度为 60 个字符,总 blob 字符数为 85。

我最近还负责开发一个登录验证系统,该系统将与在论坛注册页面上创建的用户帐户一起使用。通过这种方式,您可以将具有正确数据库连接信息的这些脚本附加到任何外部网站,即使在不同的服务器上(假设您没有使用共享主机),并根据论坛帐户信息成功验证用户登录请求。从那里您可以毫无问题地提取个人资料信息或帐户头像,甚至他们的帖子历史记录!

这是我想出的:

首先,显而易见的。设置数据库连接:

<?
    define('DB_SERVER', 'localhost');
    define('DB_USER', 'phpMyAdmin Login Here');
    define('DB_PASS', 'phpMyAdmin Password Here');
    define('DB_DATABASE', 'Typically [user_xenpubdatabase]');

    $conn = mysqli_connect(DB_SERVER, DB_USER, DB_PASS, DB_DATABASE);
        if (!$conn) {
            die('Database connection failed: ' . mysqli_connect_error());
?>

现在我还选择使用函数并将它们与登录表单分开存储,因此当用户提交时,functions.php 包含在登录中。

这是我的功能:

<?php
function sanitize($input, $conn){
    $input = trim($input); // removing spaces
    $strlenght = strlen($input);//get the length of the input
    for($i = 0; $i <= $strlenght; $i++) {//foreach sting char
        $input = stripslashes($input); // remove backslashes
    }
    $input = htmlspecialchars($input); // make sure code gets declared
    $input = mysqli_real_escape_string($conn, $input); //disable code execution
    return $input;
}

function checkForExistingAccount($username, $conn){
    if ($stmt = mysqli_prepare($conn, "SELECT id from users where username = ?")) {

        mysqli_stmt_bind_param($stmt, 's', $username);

        mysqli_stmt_execute($stmt);

        mysqli_stmt_store_result($stmt);

        if (mysqli_stmt_num_rows($stmt) > 0){//if an account returned then rip the username already exists...
            mysqli_stmt_close($stmt);
            return true;//so return true
        }
        mysqli_stmt_close($stmt);
    }
    return false;

}

function checkUsername($username, $conn){

    if ($stmt2 = mysqli_prepare($conn, "SELECT user_id FROM xf_user WHERE username = ?")){
        mysqli_stmt_bind_param($stmt2, "s", $username);

        mysqli_stmt_execute($stmt2);

        mysqli_stmt_store_result($stmt2);
        if (mysqli_stmt_num_rows($stmt2) > 0){
            mysqli_stmt_close($stmt2);
            return true;
        }
    }
    return false;
}
function getPassword($username, $conn){
    if ($stmt2 = mysqli_prepare($conn, "SELECT data FROM xf_user_authenticate WHERE username = ?")){
        mysqli_stmt_bind_param($stmt2, "s", $username);

        mysqli_stmt_execute($stmt2);

        mysqli_stmt_bind_result($stmt2, $password);
        mysqli_stmt_fetch($stmt2);

        mysqli_stmt_close($stmt2);
        $password = substr($password, 22, -3);
        return $password;
    }

}

function checkPassword($user_pass, $hashed_pass){
    if (password_verify($user_pass, $hashed_pass)) {
        return true;
    }
    return false;

}

从那里,我的登录脚本如下所示:

if (isset($_POST['login'])){
    include 'dbs.php';
    include 'functions.php';
    if (!empty($username = sanitize($_POST['username'], $conn)) && !empty($password = sanitize($_POST['password'], $conn))) {
        if (checkUsername($username, $conn)) {
            if (!empty($dbs_password = getPassword($username, $conn))) {
                if (checkPassword($password, $dbs_password)) {
                    session_start();
                    $_SESSION['active'] = 1;//never use true, some browsers are buggy with that.
                    mysqli_close($conn);//close conn then redirect
                    header('location: ../index.php');
                } else {
                    echo '<div class="danger">Sorry, you have entered wrong information</div>';
                }
            }
        } else {
            echo '<div class="danger">Sorry, no user found with the username: ' . $username . '</div>';
        }
    }
    else{
        echo '<div class="danger">You have to fill in all fields*</div>';
    }
    mysqli_close($conn);
}
于 2018-03-12T20:28:13.340 回答