mysql - 存储用户并传入单个表或单独的表

标签 mysql sql sql-server database database-design

我想为我的网站创建一个用户管理系统,

什么对安全性和性能更好。

类型 1:

table_user : user_id , user_name , user_email , user_password . user_phone ...

类型 2:

table_user : user_id , user_name , user_email ...
table_pass : user_id , user_password .
table_phone: user_id , user_phone .

哪个更好?

最佳答案

理想情况下:

  • 根本不要存储密码(即使是加密的)。存储从密码派生的哈希值
  • Salt防止rainbow attacks的密码.
  • 将散列放在单独的数据库服务器上,在其自己的防火墙和自己定义明确的 API 之后1。这个 API 应该只做三件事:
    1. 对于给定的用户名,检索相应的密码哈希。
    2. 对于给定的用户名,设置新的哈希值(以支持重置密码)。
    3. 删除给定的用户名及其哈希值(以支持用户注销)。
  • 对盐做同样的事情:将它们放在他们自己的服务器上,并放在他们自己的防火墙和 API 后面。这个 API 应该只做三件事:
    1. 对于给定的用户名,检索相应的盐。
    2. 对于给定的用户名,将新盐设置为随机值(以支持重置密码)。
    3. 删除给定的用户名及其加盐(以支持用户注销)。
  • 散列服务器和盐服务器都应该与世界(以及彼此)隔绝,并且只能从运行您的 Web 应用程序(即 PHP 或 ASP.NET 或其他...)的服务器访问。

当用户尝试通过输入用户名和密码登录时:

  • 确保这是通过 HTTPS 完成的,以便输入的数据安全地到达您的服务器。
  • 调用 API 检索用户名的密码哈希。
  • 调用 API 检索用户名的盐。
  • 对用户输入的密码进行加盐和哈希运算,并将其与检索到的哈希值进行比较。
  • 如果它们匹配,则用户被授予访问权限。

从本质上讲,哈希值是不可逆的——除了用户,没有人知道确切的密码,即使是您也不异常(exception)。如果用户忘记密码,您无法将密码发送给他们,但您可以允许他们重置密码,假设他们通过了一些额外的验证(即可以访问特定的电子邮件地址和/或回答 secret 问题)。

顺便说一句,登录是一个相对很少见的操作,所以它不太可能造成性能瓶颈,除非您完全忽视适当的索引。


1实现 Web 服务,然后仅打开该 Web 服务所需的端口,不打开其他任何端口。

关于mysql - 存储用户并传入单个表或单独的表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13322841/

相关文章:

mysql - 如何使用 SELECT FOR UPDATE

sql - 为 SQL Server 2008 R2 Express 安装 SP2

php - 我没有看到ajax的最后一次调用

java - 在 Java 中将 PDF 编码为 Base64,在 PL/SQL 中解码 : doesn't work

ASP.net - 无法获取名为的数据提供程序的提供程序工厂

java - resultSet 如何存储值

sql-server - 将 SQL Server 数据库复制到测试数据库的最简单方法?

SQL 将 id 连接成特定顺序

php - 从数据库中的特定表返回多行

php - 用于计算 mySQL 表中行数的 Wordpress 函数/插件