我在一个第三方应用程序上工作,我需要做一个独立的登录认证。我不想设置会话或创建任何类似的本地数据变量,我只想检查用户名/密码是否匹配。目前的问题是,XF身份验证系统对我来说没有多大意义。我浏览了XF的官方网站,但我没有收集到太多。我知道密码/salt数据存储在xf_user_authentication表中,但我不知道如何理解它。有没有人愿意向我解释一下密码是如何构成的,以及这个表中的内容是什么?
发布于 2018-03-13 04:28:13
将此答案发布给将来遇到此问题的任何人。
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);
}https://stackoverflow.com/questions/23945531
复制相似问题