WordPress 5.7自定义登录页重置密码时报错errors=invalidkey如何解决
错误触发的核心诱因
- 最直接的硬伤是表单提交参数和服务端读取规则完全不匹配,关键校验参数缺失:
服务端do_password_reset函数通过$_REQUEST['rp_key']、$_REQUEST['rp_login']读取密钥与登录名做校验,但自定义表单存在两处不符合规则的配置:- 重置密钥的隐藏字段仅设置了
name="key",和服务端要求的rp_key字段名不一致,服务端拿到的密钥值为空 - 用户登录名的输入框仅配置了
id="user_login",没有设置对应的name属性,表单提交时该字段不会被携带到服务端,服务端获取到的登录名值为空
空密钥+空登录名传入check_password_reset_key时,必然返回invalidkey校验失败。
- 重置密钥的隐藏字段仅设置了
- 流程逻辑存在隐患,重复调用密钥生成接口:
WordPress核心触发retrieve_password_message过滤器时,已经完成了和用户账户绑定的合法重置密钥生成,也就是过滤器直接传入的$key参数。但代码中没有使用系统传入的密钥,反而重新调用get_password_reset_key($user_data)生成全新密钥,该操作会覆盖之前存入用户账户meta的密钥值。在用户多次提交重置请求、并发触发重置流程时,很容易出现邮件携带的密钥和系统存储的密钥不匹配的问题。 - 细节漏洞未处理URL编码差异:
生成重置链接时,对用户登录名做了rawurlencode编码,但读取URL参数填充表单时没有做对应的解码操作,导致传入校验的登录名是编码后的格式,和数据库存储的真实登录名不匹配,同样会触发密钥校验失败。
具体修复步骤
- 调整自定义表单的字段配置,匹配服务端参数要求:
- 给用户登录名的输入框增加
name="rp_login"属性,value值用urldecode($_GET['login'])填充 - 将重置密钥隐藏字段的name从
key修改为rp_key,value值用urldecode($_GET['key'])填充,避免转义导致的值不匹配
- 给用户登录名的输入框增加
- 修正重置邮件的生成逻辑:
直接使用过滤器传入的$key、$user_login参数拼接邮件内容,删掉多余的$key = get_password_reset_key($user_data);代码行,避免覆盖系统已生成的合法密钥。 - 优化服务端校验的前置判断:
读取到rp_key、rp_login后先判断两个值是否为空,为空直接跳转invalidkey错误页,避免将空值传入校验函数。
内容的提问来源于stack exchange,提问作者theKing
相关产品推荐
相关产品推荐

