简体   繁体   English

如何保护我的登录页面

[英]How to secure my login page

I have a login.html webpage that lets user enter his username and password. 我有一个login.html网页,允许用户输入他的用户名和密码。 When he clicks on submit I collect the entered value using Javascript and then make a Ajax POST Call to the php file and send the username and password. 当他点击提交时,我使用Javascript收集输入的值,然后对php文件进行Ajax POST调用并发送用户名和密码。

My concern here is that is this a safe way of sending username and password ? 我担心的是,这是一种安全的方式来发送用户名和密码吗? If not how can i secure this transaction of sending data from html file to php running the backend? 如果不能如何保护这个从html文件发送数据的事务到运行后端的php?

The php file then connects to the MySql Db and checks if the user exits and if the password is correct If Yes it simply sends a Valid text back to the ajax calls to the javascript function if not I determine it is an invalid user ? php文件然后连接到MySql Db并检查用户是否退出以及密码是否正确如果是,它只是将有效文本发送回javascript函数的ajax调用,如果不是我确定它是无效用户?

I am not quite happy with this logic ? 我对这个逻辑不太满意吗? Is there a better way to implement this process ? 有没有更好的方法来实现这个过程? Since i am putting my code to production I want to secure it as much as possible. 由于我将我的代码投入生产,我希望尽可能地保护它。

The below code works fine i just need tips to secure it. 下面的代码工作正常我只需要提示来保护它。

login.html 的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 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 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);
?>

This really belongs on codereview.stackexchange.com, but I'll give it a shot anyway. 这真的属于codereview.stackexchange.com,但无论如何我都会试一试。

Firstly, I'd add a csrf token to your form to stop those types of attacks. 首先,我会在表单中添加一个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;

Then in your form, include a hidden input field: 然后在您的表单中,包含一个隐藏的输入字段:

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

Then in your ajax, add the token. 然后在你的ajax中添加令牌。

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

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

Then in your php, let's stop the undefined index errors on access of that page directly. 然后在你的php中,让我们直接在访问该页面时停止未定义的索引错误。

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

Then we need to check if the token that was passed is the same as our token 然后我们需要检查传递的令牌是否与我们的令牌相同

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

Then we need to stop using mysqli_query when accepting user data, even if sanitizing with mysqli_real_escape_string and instead use prepared statements. 然后我们需要在接受用户数据时停止使用mysqli_query ,即使使用mysqli_real_escape_string而是使用mysqli_real_escape_string prepared语句。 Also, procedural style code makes me cry, so we'll be changing that. 此外,程序式代码让我哭泣,所以我们将改变它。 Furthermore, let's return an array with a status and a message, so it's easier to handle the error and success reporting. 此外,让我们返回一个包含状态和消息的数组,这样就可以更轻松地处理错误和成功报告。

$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;

Now we need to modify your post function. 现在我们需要修改你的帖子功能。

$.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');

Finally, and most importantly, you have a plain text method of passwords being used, which makes no sense from a security perspective. 最后,最重要的是,您使用了纯文本密码方法,从安全角度来看,这没有任何意义。 This is precisely how you get hacked. 这正是你被黑客攻击的方式。 Instead, you should be using at least the sha256 hashing method. 相反,您应该至少使用sha256散列方法。 Change how the passwords are stored in the database to use sha256 then make a comparison by passing that into the SQL selector, example: 更改密码在数据库中的存储方式以使用sha256然后通过将其传递到SQL选择器进行比较,例如:

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

And when saved in the database, the password will look like fcec91509759ad995c2cd14bcb26b2720993faf61c29d379b270d442d92290eb for instance. 当保存在数据库中时,密码看起来就像fcec91509759ad995c2cd14bcb26b2720993faf61c29d379b270d442d92290eb

My answer has been for clarity sake, but in reality, you shouldn't even be reinventing things. 我的回答是为了清楚起见,但实际上,你甚至不应该重新发明事物。 There's plenty of applications and framework's out there that have placed countless hours into securing their authentication systems. 有大量的应用程序和框架已经花费了无数的时间来保护他们的身份验证系统。 I would recommend having a look into all of these, as they'll help build your core programming skills and teach fundamental OOP practices 我建议您仔细研究所有这些内容,因为它们有助于构建您的核心编程技能并教授基本的OOP实践

Hopefully this has been helpful. 希望这有用。

First of all, if you want "top" security you should use HTTPS with a valid certificate, otherwise any attacker may be able to create a Man in the middle attack and intercept your data (I guess this is your main concern). 首先,如果你想要“顶级”安全性,你应该使用带有效证书的HTTPS,否则任何攻击者都可以在中间攻击中创建一个人并拦截你的数据(我想这是你最关心的问题)。 Doing the HTTPS on the login page only is meaningless as the same attacker could do a Session Hijacking attack and impersonate other users without knowing the password. 仅在登录页面上执行HTTPS是没有意义的,因为同一攻击者可以进行会话劫持攻击并在不知道密码的情况下冒充其他用户。

Be aware that there is no difference of using AJAX or an HTML form, the data is sent though the wire in the same way. 请注意,使用AJAX或HTML表单没有区别,数据以相同的方式通过线路发送。

If you don't want to spent more resources (usually HTTPS cerficates costs money), you can go the "not that good route": pass a hashed version of the password , but this has its downsides too (if you don't hash at server side, then the password becomes the hash itself...) 如果你不想花费更多的资源(通常是HTTPS cerficates花钱),你可以去“不那么好的路线”: 传递一个哈希版本的密码 ,但这也有它的缺点(如果你不哈希)在服务器端,然后密码成为哈希本身...)

As adviced, don't try to reinvent the wheel, try using a well known framework like Laravel, or one smaller like Slim or Silex, it might be easier to migrate your code to them. 正如所建议的那样,不要试图重新发明轮子,尝试使用像Laravel这样众所周知的框架,或者像Slim或Silex这样的小型框架,将代码迁移到它们可能更容易。

At the end you must ask yourself, what is the worst case scenario if some user gets access to another account? 最后你必须问自己,如果某个用户可以访问另一个帐户,最糟糕的情况是什么? If you're deploying a trivial app with no personal data, maybe your current solution is good enough on the other hand if you're dealing with sensitive information you must pay good attention securing your website. 如果您正在部署一个没有个人数据的简单应用程序,那么另一方面,如果您处理敏感信息,您当前的解决方案就足够了,您必须注意保护您的网站。

Further reading: 进一步阅读:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM