将密码与前端或后端匹配?

Matching Passwords with Front-End or Back-End?

提问人:Victor Rodriguez 提问时间:2/13/2017 最后编辑:Victor Rodriguez 更新时间:1/17/2018 访问量:8411

问:

有没有人有关于检查匹配密码的行业标准或最佳实践的信息(例如Gmail的“密码不匹配”反馈)?它是后端、前端还是客户端流程?还是完全基于其他因素?

这是我用来注册用户的代码示例(Python with Bottle)。代码有效,但我不确定我是否应该从后端提供闪存消息(它返回“密码不匹配”),还是使用类似 JS 的东西会更好?我知道那里有脚本来验证这一点,但它们都是 JS。我的问题不是如何使用 JS,而是哪种方法是首选方法。

@route('/suser', method='POST')
def sign_suser():
    cemail = request.forms.get('semail')
    cpassword1 = request.forms.get('spass1')
    cpassword2 = request.forms.get('spass2')
    ctype = request.forms.get('stype')
    if cpassword1 != cpassword2:
        return "<p>Passwords do not match</p>"
    else:
        pwhash = crypt(cpassword1)
        connection = sqlite3.connect("whatever.db")
        cursor_v = connection.cursor()
        cursor_v.execute("insert into users (cemail, cpassword, atype) values (?,?,?)", (cemail,pwhash,ctype))
        connection.commit()
        cursor_v.close()
        info = {'status': 'User Added',
                'type': 'success'}
        return template('whatever',info)
JavaScript Python 验证 客户端

评论

2赞 Ry- 2/13/2017
后端始终是执行检查的后端,但您可以使用来自 JavaScript 的 XMLHttpRequest 发送登录请求。为了简单起见,我建议您暂时坚持使用来自后端的消息。
1赞 Elvis 2/13/2017
检查应始终在后端完成。关于正在显示的消息,您可以根据发送的 HTTP 请求的响应使用 JavaScript 显示消息。
8赞 Daniel 2/13/2017
第二个密码仅供用户使用,以防止拼写错误。这属于客户端表单验证。我只会在请求中发送一个密码字符串。
3赞 Darkrum 2/13/2017
@Daniel说了同样的话。您可以检查两个密码是否与客户端匹配,以防拼写错误,并且仅将一个密码字段发送到服务器进行保存。真的没有理由检查服务器端,如果有人绕过您的客户端逻辑,那么如果他们搞砸了密码,那就是他们。服务器应发出的唯一消息是密码字段是否丢失。
0赞 Victor Rodriguez 2/13/2017
很棒的反馈,谢谢大家。我将探讨事物的客户端部分。再次感谢你

答:

-1赞 ssc-hrep3 2/13/2017 #1

您需要区分两种情况:

  1. 如果不在后端使用数据库或任何不可共享的技术,则无法验证该值。在这种情况下,您唯一可能的情况是在后端检查它(例如,通过 Ajax 调用或通过 WebSocket 进行通信)。这种验证的示例包括:用户名/密码验证或任何需要连接到数据库的东西,一种专有算法,用于检查具有无法发布的逻辑的值
  2. 您可以验证该值,而无需先在后端(数据库)中检查它。在这种情况下,您可以出于性能原因将检查移至前端/客户端。您仍然必须保护后端免受不正确值的侵害(以防发生攻击、损坏的 JavaScript 等)此类检查的示例包括电子邮件地址验证、电话号码验证等。

对于 1,我只会在提交值或键入时使用与后端的常规连接(如果后端的响应足够快)。

对于 2,您有以下几个选项:

  • 像在 1 中一样做。在提交时或输入期间进行后端检查。不过,这可能会有一些性能问题(主要是如果您在按下键时检查它)。如果您在提交后进行检查,则验证不是实时的。
  • 在前端和后端进行单独的验证。如果你正在做。建议这样做。您正在前端和后端之间复制代码。尽可能避免它。
  • 在前端和后端使用共享验证模式来做到这一点。这是我推荐的验证值的方法。如果使用正则表达式 (regex) 完成检查,则此验证效果最佳。后端有一个模式的 Map(),这些模式通过前端的接口提供。这些模式最初在加载 Web 应用程序时加载,然后在应用程序的运行时出现。这样可以确保后端和前端的验证始终相同。

但是,您的示例包括两个密码的匹配(相等检查)。这是一种特殊情况,因为不能使用正则表达式来检查值的有效性。这排除了上面推荐的情况,并留下了另外两个提到的解决方案。

如果您的唯一目的是比较这两个值,我建议您复制逻辑。在这种情况下,复制在某种程度上是合理的(恕我直言),因为检查非常简单,并且不太可能随着时间的推移而改变。对后端进行检查以检查是否相等(恕我直言)被夸大了。

评论

5赞 Darkrum 2/13/2017
你的答案很长,完全错过了问题的真正含义。
40赞 Darkrum 2/13/2017 #2

在注册期间检查两个密码字段是否匹配应完全使用客户端逻辑完成。它是为了防止用户错误地将拼写错误插入密码而提供的。服务器端检查是没有意义的,因为你的客户会阻止它,如果你的用户是一个精通技术的人,用 curl 做所有事情,那么如果他们搞砸了,那就由他们来做。

此外,我还将详细阐述您关于最佳实践的问题。您不应立即将用户保存在数据库中,除非他们首先通过链接(通常发送到他们的电子邮件)验证该链接是否有效。请记住:永远不要相信用户提供的任何内容。

评论

1赞 Victor Rodriguez 2/13/2017
有道理,尤其是第二部分!谢谢