如何创建一个安全的无需使用SQL的单用户登录?

3

我计划创建一个小型 Web 服务来托管在我的网站上,但是我想知道如何创建一个简单且安全的登录表单(用户名+密码)仅适用于一个特定的用户名和密码组合,而无需使用 SQL。这不必非常安全,但如果仅通过窥视源代码就能破解它那就太糟糕了。是否可以实现这一点?

4个回答

2

看起来很不错,但我不确定如何实现它。 - Fin Moorhouse
+1,这是您最好的方法。@Fin Moorhouse:如果您的Web服务器是Apache,请查看此页面:http://www.elated.com/articles/password-protecting-your-pages-with-htaccess/ - ChristopheD
@ChristopheD,这看起来很棒,我已经试过一个类似的教程,但是结果有些奇怪。页面确实提示我登录,但是之后我只能看到我的404页面-登录后在目录中看不到任何内容。然后我非常仔细地按照你链接的教程操作,同样的问题出现了-用户名/密码无法访问放置htaccess的目录。非常令人沮丧。 - Fin Moorhouse

1

您是否拥有某种服务器端脚本?JavaScript无法实现。

由于您说它不需要完全安全,因此可以使用哈希和盐来创建一些东西,这些东西不能通过查看源代码来“破解”。请注意,如果您没有通过https连接,则您的本地网络、ISP、政府等恶意用户将能够窃听通信并看到您传输明文密码。仅出于这个原因,密码不应在任何地方重复使用其他人登录的影响应该很小

以下是如何生成哈希的简单示例:

<?php
    $salt = "can-be-anything";
    $password = "password";
    $hash = hash_pbkdf2( "sha256", $password, $salt, 1024, 0 );
    echo $hash;
?>

我们的结果是5b24ad89b5e94c35537f6967b39cf294aa845f94440ebfdd3e857e4cf5f41d7e。现在,当接收密码并比较两个哈希值时,您可以遵循相同的过程。如果减少迭代次数,则破解哈希值将更容易,但会降低服务器负载。

优点

  • 可以将散列密码存储在同一文件中
  • 查看源代码的人无法了解您的密码
  • 破解存储的密码的复杂度随密码长度变化而变化

缺点

  • 没有安全保证,某些人最终可能会获得访问权限
  • 如果不使用https,则攻击者可以从被动网络监视中了解您的密码

这是一个很好的答案- 我只是把它当作一个挑战,显然这绝不是一个特别好的想法!如果被破解了,这可能是一个适用于单个用户登录且影响较小的最佳计划- 再次感谢。 - Fin Moorhouse
作为对此的跟进,我应该如何保护那个安全目录中的页面不被未登录的人访问?例如,如果login.php进入welcome.html,我该如何阻止随机访客查看welcome.html并破坏我们使用此功能的原因? - Fin Moorhouse
1
@Fin 你还需要使用服务器端脚本。例如,你可以使用 _welcome.php_。就像大多数登录系统一样,你可以开始一个会话。在 PHP 中,你可以使用 session_start() 并且你可以添加数据,比如用户名到 $_SESSION ($_SESSION["username"] = "Fin")。其他语言也会有类似的东西。然后你可以在 welcome.php 中加载该会话,如果你的数据不存在,你可以显示一个错误或重定向到登录页面。希望我对注释的格式理解正确。 - R3dclient

1
您可以使用 Berkeley DB,它是一个以文件形式存储的键值数据库。它没有服务器,但支持并发访问。请确保将文件放在Web服务器不会提供服务的地方(换句话说,不要将其放在用户访问的CGI脚本旁边)。
编辑:提问者澄清希望实现极其简单,具有“有限的网页设计理解”。在这种情况下,请将用户名和密码放在文本文件中(纯文本、JSON、CSV或其他您的编程语言最容易解析的格式),放在Web服务器不提供服务的地方,并只允许Web服务器读取。您还应该对密码进行哈希处理(该链接是针对PHP的,但在其他语言中也非常类似)。

与其他答案一样,尽管这看起来可能是一个不错的解决方案,但它远超出了我对网页设计的有限理解-无论如何还是谢谢。 - Fin Moorhouse

1
你可以使用OAuth提供程序(Facebook,Google,Twitter,LinkedIn),甚至启用两步验证。
设置非常简单,这里是一个使用Google的PHP示例:

https://github.com/google/google-api-php-client/blob/master/examples/idtoken.php

这里是另一个使用Facebook的例子:

https://github.com/facebook/facebook-php-sdk-v4/tree/f1916f3a1e8aeece518a18dc88f05775aadb9840/examples/login-logout-get-profile

谷歌和 Facebook 都为所有主要语言提供了 API,但如果您喜欢,也可以使用任何标准的 OAuth 客户端。甚至可以实现自己的客户端,实际上客户端相当简单。


@codedocle 谢谢你的分享。我刚花了一些时间研究htpsswd和htaccess身份验证,看起来一个可行的方法是不让Apache服务器列出目录,然后检查是否存在与密码标题相对应的文件,但我真的应该研究一下SQL及其关系型数据库管理系统。 - Fin Moorhouse
HTTP基本身份验证非常容易设置,因为它已经在(几乎所有)客户端和服务器上实现,您只需要部署它,所以这是一个非常好的选择。无论如何,如果与SQL的麻烦是您不想设置SQL服务器并且它只是一个单一登录应用程序,并且您不必担心高并发,那么您可能可以使用SQLite。它比MySQL容易得多,并且可以轻松地嵌入到您的应用程序中,因为它不需要服务器。甚至还有更简单的方法,例如使用CSV文件(大多数语言都在其标准库中实现了解析器)。 - NotGaeL
1
虽然将 password_hashuser_id 设置为非空并将 user_id 设为唯一索引(CREATE TABLE myapp.users (userid VARCHAR(255) UNIQUE KEY NOT NULL, hashed_password VARCHAR(255) NOT NULL))不需要太多的努力。 - NotGaeL
1
数据库存储在依赖于引擎的文件格式中。MySQL上的默认引擎是InnoDB,但美妙之处在于您不需要担心这个问题(除非您是高级用户)。MySQL服务器是一个在端口上监听MySQL客户端连接的服务器,就像Web服务器监听HTTP连接一样。您的应用程序充当客户端连接到服务器并根据您的命令创建/读取/更新/删除记录。每种编程语言都包括所需的客户端驱动程序和函数,以连接到服务器并发送MySQL查询,就像我向您展示的那些一样。 - NotGaeL
1
SQLite使用相同的语言(SQL),但没有服务器。驱动程序锁定数据库文件,执行查询并相应地更新文件,然后解锁文件。读锁允许其他读锁(但不允许写入),而写锁在释放锁之前不允许访问,并且所有锁都由驱动程序自动执行。您只需指定数据库文件并发送查询即可,这就是您需要担心的全部。 - NotGaeL
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接