[英]user authentication with php class. is this right?
這是我第一次創建類。
我創建了一個User類,用於登錄,注冊和注銷。
看來它正在工作,但我確定我做錯了什么。 例如,當我僅使用login()方法時,為什么必須給出在___construct中創建的所有變量。 登錄時,我只需要用戶名和密碼。
我在模板系統中使用$ _ERROR變量顯示錯誤。 我如何在課堂上顯示錯誤。 我用過拋出新的ExampleException
誰能復習我的課,然后告訴我我犯的錯誤? 我只是想學習如何使用課堂...
這是我的課
<?php
class User
{
var $Username = '';
var $Email = '';
var $Password = '';
var $Salt = '';
protected $_username;
protected $_email;
protected $_password;
protected $_salt;
protected $_db;
protected $_user;
public function __construct(PDO $db, $Username, $Email, $Password, $Salt)
{
$this->_db = $db;
$this->_username = $Username;
$this->_email = $Email;
$this->_password = $Password;
$this->_salt = $Salt;
}
private function saltString($Password) // Creates random string for password
{
$Characters = 'PEcN0';
$string = md5( $Password . $Characters );
return $string;
}
public function login() // checks if CheckCredentials is true. if it's true it creates sessions
{
$user = $this->_CheckCredentials();
if($user){
$this->_user = $user;
$_SESSION['UserID'] = $user['UserID'];
$_SESSION['Username'] = $user['Username'];
$_SESSION['Level'] = $user['Level'];
$_SESSION['Reputation'] = $user['Reputation'];
return $user['UserID'];
}
return false;
}
public function register() // checks if addUser is true.
{
$user = $this->_addUser();
if($user){
$this->createSession($user);
}
return false;
}
public function _CheckCredentials() // checks password and username for login method
{
$sql = $this->_db->query("SELECT * FROM users WHERE Username = '" . $this->_username . "'");
if($sql->rowCount() > 0){
$user = $sql->fetch(PDO::FETCH_ASSOC);
$pass = $this->saltString($this->_password);
if($pass == $user['Password']){
$sql = $this->_db->query( "UPDATE users SET LastLogin = NOW() WHERE UserID = '" . $user['UserID'] . "'" );
return $user;
}
}
return false;
}
public function _addUser() // add user into database
{
$sql = $this->_db->query( "SELECT * FROM users WHERE Username = '" . $this->_username . "' OR Email = '" . $this->_email . "'" );
if($sql->rowCount()){
$user = $sql->fetch(PDO::FETCH_ASSOC);
if($user['Username'] == $this->_username){
throw new ExampleException("This username was taken.");
}else{
throw new ExampleException("This e-mail address is being used.");
}
}else{
$intert = $sql->query( "INSERT INTO users ( UserID, OauthUid, OauthProvider, Username, Password, Email, CookieKey, Level, Registered, LastLogin, Reputation, Contents )
VALUES ( NULL, '". $UserID ."', '". $Provider ."', '" . $Username . "', '" . $Password . "', '" . $Email . "', '" . generateKey( 5 ) . "', '1', NOW(), NOW(), '0', '0')" );
$UserID = $sql->lastInsertId();
if($instert){
$_SESSION['UserID'] = $UserID;
$_SESSION['Username'] = $Username;
$_SESSION['Level'] = '1';
}
}
return false;
}
public function getUser()
{
return $this->_username;
}
}
?>
這就是我的使用方式...
<?php
if ( isset( $_POST['Username'] ) )
{
$Username = trim( $_POST['Username'] );
$Password = trim( $_POST['Password'] );
if ( !preg_match( '/^[a-z0-9_]+$/i', $Username ) )
$_ERROR = 'bad username!';
else
{
$UserClass = new User($dbc, $Username, $Email, $Password, $Salt);
if($userid = $UserClass->login())
{
if ( isset( $_POST['Remember'] ) )
{
setcookie( 'UserID', $data['UserID'], time() + 31536000, '/', SITE );
setcookie( 'PassHash', md5( $data['Password'] . $data['CookieKey'] ), time() + 31536000, '/', SITE );
}
header( "Location: " . ( $_POST['Redirect'] != '' ? base64_decode( $_POST['Redirect'] ): '/index.php' ) );
die();
}
else
$_ERROR = "Check your username or password!";
$_INFO .= $_SESSION['UserID'];
}
}else{
$Reff = '';
if ( isset( $_SERVER['HTTP_REFERER'] ) )
$Reff = base64_encode( $_SERVER['HTTP_REFERER'] );
$_INFO .= $_SESSION['UserID'];
$_PAGE .= t_LoginForm( $Reff );
}
?>
您使用的PDO總是一個加號,但問題是您沒有綁定參數。 PDO的最大優點實際上是綁定參數。 在您的示例中:
$sql->bindParam(':userid',$UserID);
$sql->bindParam(':provider',$Provider);
等等...............
第二部分讓我感到恐懼,如果您讀過密碼安全性知識,應該會嚇到您嗎?這是您使用md5作為密碼,而只是帶有一個剛剛串聯的隨機字符串$ characters? 那位先生...很...愚蠢(抱歉,直言不諱,但這實際上是一個大問題,可能會給您的客戶/用戶帶來很多麻煩,而這真的很嚴重)。
在這里試試這個Bcrypt庫 。 在2013年,即使添加鹽或使用這樣的方法,也不應使用md5:
$Characters = 'PEcN0';
$string = md5( $Password . $Characters );
return $string;
相信我不要建立自己的“加密/散列”方法,而要使用社區信任的方法。
同樣回到PDO部分,不要忘記將其添加到屬性中:
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
希望您從這篇文章中學到一些東西。 您不應該在沒有bindParam的情況下使用PDO,並且無論有沒有鹽都不要使用MD5。 Bcrypt Bcrypt Bcrypt Bcrypt Bcrypt。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.