当前位置: 首页 > 面试题库 >

如何保护我的登录页面

牛经赋
2023-03-14
问题内容

我有一个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和使用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练习。

  • Lararvel 4.x
  • Zend 2
  • hal
  • YII

希望这对您有所帮助。



 类似资料:
  • 我有一个示例web应用程序,它使用Google的Spring OAuth2身份验证。HttpSecurity配置如下: 现在,每当发出未经身份验证的请求时,此配置都会将浏览器重定向到登录页面。此页面显示了指向谷歌身份验证的链接 通过谷歌登录以及登录表单。 但我希望浏览器直接重定向到Google的身份验证服务器,而不是应用程序的登录页面。我不想要任何表单登录/注册功能。我只想让用户使用谷歌登录。 为

  • 问题内容: 您好 ,我为编写的PHP代码所困扰。我盯着这个看了好几个小时都没有成功,请帮忙找出我显然已经解决的所有错误。 我想要此脚本执行的操作是从html表单页面中查询数据库表(“用户”)以确保其密码和用户名正确,然后在单独的表(“令牌”)中插入随机令牌(我以前使用过的方法,它可以正常工作)进入“ tk”列,然后用户进行常规身份验证。代码从“用户”表拉入“令牌”表中的“ gauth”列。 进行其

  • 本文向大家介绍Android登录时密码保护功能,包括了Android登录时密码保护功能的使用技巧和注意事项,需要的朋友参考一下 在很多的Android项目中都需要用户登录、注册。这样的话在开发中做好保护用户密码的工作就显得尤为重要。这里我把自己的密码保护方法记录下来。 这是我建了一个保存密码的文件,以便于检查自己保存密码或者上传到服务器的时候密码是否已经被保护了。这就是当我输入用户名和密码之后点击

  • 我正在使用Apache Camel为另一个Camel应用程序托管REST API。如何保护这个REST API?它只能通过HTTPS访问? 我使用的是Camel 3.0.0-M1。对于REST API,我使用的是REST DSL和camel-jetty组件。从关于SO和camel邮件列表的其他问题中,我收集到我只需要配置jetty组件即可启用SSL。 这就是我想到的: 我预计我的API只能通过ht

  • 使用CSRF保护,这样从其他网站发出的任何请求都不会影响我的网站造成伤害。在Spring安全csrf留档中说,csrf应用于放帖补丁删除请求。 但据我了解,登录/注册表单不需要csrf保护,因为它们已经需要用户名和密码形式的凭据,即使是从另一个网站发出这样的请求,也不会有任何伤害,因为用户只需登录即可。 但是由于登录通常是一个发布请求,csrf将在Spring默认情况下自动应用。这意味着我需要将c

  • 我一直在想办法锁定我的大摇大摆的用户界面。使用Oauth 2.0登录屏幕后的html页面,最终能够通过JWT识别用户。 我已经设法找到了如何包含授权按钮,但我更希望在成功登录之前,API方法不可见。解决这个问题的最佳方法就是重定向到一个带有登录屏幕的单独页面吗?是否有一种简单的方法可以在Swagger配置文件中实现这一点?