簡體   English   中英

如何保護我的登錄頁面

[英]How to secure my login page

我有一個login.html網頁,允許用戶輸入他的用戶名和密碼。 當他點擊提交時,我使用Javascript收集輸入的值,然后對php文件進行Ajax POST調用並發送用戶名和密碼。

我擔心的是,這是一種安全的方式來發送用戶名和密碼嗎? 如果不能如何保護這個從html文件發送數據的事務到運行后端的php?

php文件然后連接到MySql Db並檢查用戶是否退出以及密碼是否正確如果是,它只是將有效文本發送回javascript函數的ajax調用,如果不是我確定它是無效用戶?

我對這個邏輯不太滿意嗎? 有沒有更好的方法來實現這個過程? 由於我將我的代碼投入生產,我希望盡可能地保護它。

下面的代碼工作正常我只需要提示來保護它。

的login.html

<div>
    <h3>Login information</h3>

    <input type="text" name="user" id="usrnm" placeholder="Username/Email">
    <input type="password" name="pswdlogin" id="pswdlogin" placeholder="Password">
    <input type="checkbox" name="keepmeloggedin" id="keepmeloggedin" value="1" data-mini="true">
    <input type="submit" data-inline="false" onclick="logmein()" value="Log in">
    <div id="loginstatus">    </div>
 </div>

logmein.js

function logmein() {

  var usrnm = document.getElementById("usrnm").value;
  var pswdlogin = document.getElementById("pswdlogin").value;

  $.post("http://xyz/mobile/php/logmein.php",
    {
      usrnm: usrnm,
      pswdlogin: pswdlogin
    },
    function(data, status) {

      if (data == 'Valid') {

        window.open("http://xyz/mobile/home.html?email=" + usrnm + "", "_parent");

      } else {
        alert(data);
        document.getElementById("loginstatus").innerHTML = data;
      }
    });
}

logmein.php

<?php

$usrnm_original = $_POST['usrnm'];
$pswdlogin_original = $_POST['pswdlogin'];

$con = mysqli_connect("localhost", "cSDEqLj", "4GFU7vT", "dbname", "3306");

if (mysqli_connect_errno())
    {
    echo "Failed to connect to MySQL: " . mysqli_connect_error();
    }

mysqli_select_db($con, "dbname");
$usrnm = mysqli_real_escape_string($con, $usrnm_original);
$pswdlogin = mysqli_real_escape_string($con, $pswdlogin_original);

$result = mysqli_query($con, "SELECT * FROM registration WHERE email = '" . $usrnm . "' AND password='" . $pswdlogin . "' ");
$rows = mysqli_num_rows($result);

if ($rows == 1)
    {
    echo "Valid";
    }
  else
    {
    echo "In Valid Credentials Entered";
    }

mysqli_close($con);
?>

這真的屬於codereview.stackexchange.com,但無論如何我都會試一試。

首先,我會在表單中添加一個csrf令牌來阻止這些類型的攻擊。

//the most simple type of csrf token
if (!isset($_SESSION['token'])):
    $token = md5(uniqid(rand(), TRUE));
    $_SESSION['token'] = $token;
else:
    $token = $_SESSION['token'];
endif;

然后在您的表單中,包含一個隱藏的輸入字段:

<input type="hidden" name="token" id="token" value="<?php echo $token; ?>"/>

然后在你的ajax中添加令牌。

var usrnm = $('#usrnm').val();
var pswdlogin = $('#pswdlogin').val();
var token = $('#token').val();

{
    usrnm: usrnm,
    pswdlogin: pswdlogin,
    token: token
}

然后在你的php中,讓我們直接在訪問該頁面時停止未定義的索引錯誤。

$usrnm_original = isset($_POST['usrnm'])?$_POST['usrnm']:false;
$pswdlogin_original = isset($_POST['pswdlogin'])?$_POST['pswdlogin']:false;
$token = isset($_POST['token'])$_POST['token']:false;

然后我們需要檢查傳遞的令牌是否與我們的令牌相同

if(!$_SESSION['token'] == $token):
    die('CSRF Attacks are not allowed.');
endif;

然后我們需要在接受用戶數據時停止使用mysqli_query ,即使使用mysqli_real_escape_string而是使用mysqli_real_escape_string prepared語句。 此外,程序式代碼讓我哭泣,所以我們將改變它。 此外,讓我們返回一個包含狀態和消息的數組,這樣就可以更輕松地處理錯誤和成功報告。

$ret = array();
$mysqli = new mysqli("localhost", "cSDEqLj", "4GFU7vT", "dbname");

if($sql = $mysqli->prepare('SELECT * FROM registration WHERE email = ? and password = ?')):
    $sql->bind_param('ss', $usrnm_original, $pswd_original);

    if($sql->execute()):

        $sql->fetch();

        if($sql->num_rows > 0):
            $ret['status'] = true;
            $ret['msg'] = 'You have successfully logged in! Redirecting you now';
        else:
            $ret['status'] = false;
            $ret['msg'] = 'The credentials supplied were incorrect. Please try again';
        endif;
    endif;
    $sql->close();
    return json_encode($ret);
endif;

現在我們需要修改你的帖子功能。

$.post("http://xyz/mobile/php/logmein.php",
{
  usrnm: usrnm,
  pswdlogin: pswdlogin,
  token:token
},
function(data) {

  if (data.status == true) {

    window.open("http://xyz/mobile/home.html?email=" + usrnm + "", "_parent");

  } else {
    alert(data.msg);
    $('#loginstatus').text(data.msg);
  }
}, 'json');

最后,最重要的是,您使用了純文本密碼方法,從安全角度來看,這沒有任何意義。 這正是你被黑客攻擊的方式。 相反,您應該至少使用sha256散列方法。 更改密碼在數據庫中的存儲方式以使用sha256然后通過將其傳遞到SQL選擇器進行比較,例如:

$pswdlogin_original = isset($_POST['pswdlogin'])? hash('sha256', $_POST['pswdlogin']):false;

當保存在數據庫中時,密碼看起來就像fcec91509759ad995c2cd14bcb26b2720993faf61c29d379b270d442d92290eb

我的回答是為了清楚起見,但實際上,你甚至不應該重新發明事物。 有大量的應用程序和框架已經花費了無數的時間來保護他們的身份驗證系統。 我建議您仔細研究所有這些內容,因為它們有助於構建您的核心編程技能並教授基本的OOP實踐

希望這有用。

首先,如果你想要“頂級”安全性,你應該使用帶有效證書的HTTPS,否則任何攻擊者都可以在中間攻擊中創建一個人並攔截你的數據(我想這是你最關心的問題)。 僅在登錄頁面上執行HTTPS是沒有意義的,因為同一攻擊者可以進行會話劫持攻擊並在不知道密碼的情況下冒充其他用戶。

請注意,使用AJAX或HTML表單沒有區別,數據以相同的方式通過線路發送。

如果你不想花費更多的資源(通常是HTTPS cerficates花錢),你可以去“不那么好的路線”: 傳遞一個哈希版本的密碼 ,但這也有它的缺點(如果你不哈希)在服務器端,然后密碼成為哈希本身...)

正如所建議的那樣,不要試圖重新發明輪子,嘗試使用像Laravel這樣眾所周知的框架,或者像Slim或Silex這樣的小型框架,將代碼遷移到它們可能更容易。

最后你必須問自己,如果某個用戶可以訪問另一個帳戶,最糟糕的情況是什么? 如果您正在部署一個沒有個人數據的簡單應用程序,那么另一方面,如果您處理敏感信息,您當前的解決方案就足夠了,您必須注意保護您的網站。

進一步閱讀:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM