You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SurrealDB用户Scope无重复注册校验、登录鉴权失效问题咨询

问题

我创建了如下Scope:

DEFINE SCOPE user SESSION 1d
        SIGNUP ( CREATE user SET user = $user, pass = crypto::argon2::generate($pass) )
        SIGNIN ( SELECT * FROM user WHERE user = $user AND crypto::argon2::compare(pass, $pass));

随后执行注册操作,请求体如下:

{
    "ns": "test",
    "db": "test",
    "sc": "user",
    "email": "tobie@surrealdb.com",
    "pass": "some password",
    "marketing": true,
    "tags": [
        "rust",
        "golang",
        "javascript"
    ]
}

返回结果:

{
    "code": 200,
    "details": "Authentication succeeded",
    "token": "eyJ0eXAiOiJKV1QiLCJhbGciOEQiI6InRlc3QiLCJTQyI6InVzZXIiLCJJRCI6InVzZXI6czFiN3JzcnlxNW9jdDVmM2FrdHEifQ.oy7ox2QCqNDAyZnvRmGPoU2t3QmzB38J67ynpRVPfd8nXfRw0RQPunQ04KTrtzfQeNHB5Zv8-nN0HrOuqxG78w"
}

之后尝试登录,请求体:

{
    "ns": "test",
    "db": "test",
    "sc": "user",
    "email": "tobie@surrealdb.com",
    "pass": "some password"
}

登录成功返回200。但使用未注册的邮箱tobiedsfds2@surrealdb.com登录时,仍返回200成功响应;同时使用已注册的邮箱重复注册时,也能成功完成。请问这是什么原因?

分析与解决

核心问题1:请求参数与Scope变量不匹配

你的Scope定义里,SIGNUP和SIGNIN逻辑都用了$user变量,但实际注册、登录请求传递的是email字段,而非user字段。这会导致:

  • 注册时,$user取不到有效值,最终创建的user记录中user字段为空(或NULL)
  • 登录时,$user同样无有效值,查询条件变成WHERE user = NULL AND ...,SurrealDB中NULL = NULL的判断会匹配所有user字段为空的记录,只要你传的密码和这些记录的哈希值匹配(你每次都用some password),就会返回登录成功。

核心问题2:缺少唯一约束允许重复注册

你的SIGNUP逻辑只是简单执行CREATE user,没有对用户标识字段(比如email)添加唯一约束,所以即使使用同一个邮箱,也能重复创建新的user记录。

修复方案

  1. 统一参数与字段名:把Scope中的$user改为$email,和请求字段对应,同时调整存储字段:
DEFINE SCOPE user SESSION 1d
        SIGNUP ( CREATE user SET email = $email, pass = crypto::argon2::generate($pass) )
        SIGNIN ( SELECT * FROM user WHERE email = $email AND crypto::argon2::compare(pass, $pass));
  1. 添加唯一约束:创建user表时给email字段加唯一约束,从根源防止重复注册:
DEFINE TABLE user SCHEMAFULL;
DEFINE FIELD email ON TABLE user TYPE string ASSERT $value IS UNIQUE;
DEFINE FIELD pass ON TABLE user TYPE string;

也可以在SIGNUP逻辑中用CREATE IF NOT EXISTS临时规避,但表约束的方式更严谨:

SIGNUP ( CREATE IF NOT EXISTS user SET email = $email, pass = crypto::argon2::generate($pass) )

内容的提问来源于stack exchange,提问作者Shivam Sahil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 10:21:12