App Inventor 2 注册登录功能教程 - 网络微数据库实现用户系统

« 返回首页

概述

用户注册登录是很多App的基础功能。账号系统要处理密码保存、验证码、令牌过期,自己写既费事又容易留下安全漏洞,所以正式 App 用现成的认证服务,网络微数据库只用来理解原理。

方案 后端 难度 适合场景
CloudBase 认证组件 腾讯云开发(国内) ⭐⭐ 国内用户的正式 App
Supabase 认证组件 Supabase(海外,国内可访问) ⭐⭐ 不想实名认证、邮箱注册即可
网络微数据库 自建或国内免费服务 ⭐⭐ 学习注册登录的原理

两个拓展都需要先在各自控制台创建项目,具体步骤见拓展文档的“开发前准备工作”。

方案一:CloudBase 邮箱注册与密码登录

CloudBase 注册要先验证邮箱:发验证码 → 校验验证码得到 verification_token → 带着它注册。三步都是异步的,结果在各自的事件里拿到。接口返回的 data 是 JSON 文本,用 Web 客户端组件的 JsonTextDecodeWithDictionaries 解析成字典再取字段。

界面组件:文本输入框_邮箱、文本输入框_验证码、文本输入框_用户名、文本输入框_密码、按钮_发验证码、按钮_注册、按钮_登录、标签_状态,以及 CloudBaseAuth1、Web客户端1。

global verificationId = ""

when 按钮_发验证码.Click() {
  CloudBaseAuth1.SendVerificationCode(文本输入框_邮箱.Text, "", "")
}

when CloudBaseAuth1.VerificationCodeSent(responseCode, data) {
  verificationId = dictGet(Web客户端1.JsonTextDecodeWithDictionaries(data), "verification_id", "")
  标签_状态.Text = "验证码已发送,请查收邮箱"
}

when 按钮_注册.Click() {
  CloudBaseAuth1.VerifyVerificationCode(verificationId, 文本输入框_验证码.Text)
}

when CloudBaseAuth1.VerificationCodeVerified(responseCode, data) {
  var token = dictGet(Web客户端1.JsonTextDecodeWithDictionaries(data), "verification_token", "")
  CloudBaseAuth1.SignUpWithEmail(文本输入框_邮箱.Text, token, 文本输入框_用户名.Text, 文本输入框_密码.Text)
}

when CloudBaseAuth1.SignUpSuccess() {
  标签_状态.Text = "注册成功,已自动登录"
}

when 按钮_登录.Click() {
  CloudBaseAuth1.SignInWithPassword(文本输入框_用户名.Text, 文本输入框_密码.Text)
}

when CloudBaseAuth1.SignInSuccess() {
  标签_状态.Text = join("登录成功,用户ID:", CloudBaseAuth1.UserId)
}

when CloudBaseAuth1.RequestFailed(operation, errorCode, errorMessage) {
  标签_状态.Text = join("失败(", operation, "):", errorMessage)
}

登录成功后,同一屏幕里的 CloudBaseNoSQL、CloudBaseStorage 等组件把 CloudBaseAuth 属性指向 CloudBaseAuth1,就会自动带上登录令牌。跨屏幕使用、手机号注册、找回密码见 CloudBase 拓展文档。

方案二:Supabase 邮箱注册与登录

Supabase 注册只要邮箱和密码。项目默认开启“邮箱确认”,注册后要先点邮件里的链接才能登录;课堂演示可以在控制台 Authentication 设置里关闭确认。

when 按钮_注册.Click() {
  SupabaseAuth1.SignUpWithEmail(文本输入框_邮箱.Text, 文本输入框_密码.Text)
}

when SupabaseAuth1.SignUpSuccess() {
  标签_状态.Text = "注册成功"
}

when 按钮_登录.Click() {
  SupabaseAuth1.SignInWithEmailPassword(文本输入框_邮箱.Text, 文本输入框_密码.Text)
}

when SupabaseAuth1.SignInSuccess() {
  微数据库1.StoreValue("refreshToken", SupabaseAuth1.RefreshToken)
  标签_状态.Text = "登录成功"
}

when SupabaseAuth1.RequestFailed(operation, errorCode, errorMessage) {
  标签_状态.Text = join("失败(", operation, "):", errorMessage)
}

下次打开免登录:把保存的刷新令牌写回去再刷新一次,成功即为已登录。

when Screen1.Initialize() {
  var saved = 微数据库1.GetValue("refreshToken", "")
  if saved != "" {
    SupabaseAuth1.RefreshToken = saved
    SupabaseAuth1.RefreshAccessToken()
  }
}

when SupabaseAuth1.RefreshAccessTokenSuccess() {
  微数据库1.StoreValue("refreshToken", SupabaseAuth1.RefreshToken)
  标签_状态.Text = "已自动登录"
}

方案三:网络微数据库(学习原理)

用网络微数据库自己实现一遍,可以看清注册登录到底在做什么:注册就是“用户名作标签、资料作值”存一条,登录就是按用户名取回来比对密码。

这种做法把密码存在任何知道服务地址的人都能读取的地方,只适合学习,不要用在正式 App 里。

数据存储结构

标签:user_张三
值:{"password": "123456", "nickname": "张三", "createdAt": "2026-05-18"}

注册与登录积木块

注册要先查用户名是否已被占用,登录要先取回资料,两者的结果都回到同一个“已获得值时”事件,所以用全局变量 mode 区分。标签不存在时,组件拿到的值是空文本。

global mode = ""

when 按钮_注册.Click() {
  if 文本输入框_用户名.Text == "" or 文本输入框_密码.Text == "" {
    标签_状态.Text = "用户名和密码不能为空"
  } else if textLength(文本输入框_密码.Text) < 6 {
    标签_状态.Text = "密码至少6位"
  } else {
    mode = "注册"
    网络微数据库1.GetValue(join("user_", 文本输入框_用户名.Text))
  }
}

when 按钮_登录.Click() {
  mode = "登录"
  网络微数据库1.GetValue(join("user_", 文本输入框_用户名.Text))
}

when 网络微数据库1.GotValue(tagFromWebDB, valueFromWebDB) {
  if mode == "注册" {
    if valueFromWebDB == "" {
      网络微数据库1.StoreValue(tagFromWebDB, {"password": 文本输入框_密码.Text, "nickname": 文本输入框_用户名.Text})
      标签_状态.Text = "注册成功"
    } else {
      标签_状态.Text = "用户名已存在"
    }
  } else if mode == "登录" {
    if valueFromWebDB == "" {
      标签_状态.Text = "用户名不存在"
    } else if dictGet(valueFromWebDB, "password", "") == 文本输入框_密码.Text {
      微数据库1.StoreValue("currentUser", 文本输入框_用户名.Text)
      标签_状态.Text = "登录成功"
    } else {
      标签_状态.Text = "密码错误"
    }
  }
  mode = ""
}

when 网络微数据库1.WebServiceError(message) {
  mode = ""
  标签_状态.Text = join("网络错误:", message)
}

记住登录与退出

登录成功时已经把用户名存进本地微数据库,启动时读到就直接进入主屏幕;退出时清掉。

when Screen1.Initialize() {
  if 微数据库1.GetValue("currentUser", "") != "" {
    openAnotherScreen("Screen_Main")
  }
}

when 按钮_退出.Click() {
  微数据库1.ClearTag("currentUser")
}

网络微数据库后台怎么搭,见网络微数据库后台搭建教程。

常见问题

Q1:注册登录安全性如何保障?

  • 用 CloudBase / Supabase 的认证组件,密码由认证服务加密保存,你自己的数据库里不出现明文密码。
  • 不要把密码明文存进网络微数据库、云数据库或本地微数据库。
  • “记住密码”应该保存登录令牌,而不是保存密码本身。

Q2:多设备同时登录怎么办?

认证服务给每台设备各发一份令牌,可以同时登录。要限制只能一台设备在线,需要在云函数里自己记录和校验。

Q3:忘记密码怎么处理?

  • CloudBase:SendVerificationCode 发验证码 → VerifyVerificationCode 得到 verification_token → ResetPassword 设新密码。
  • Supabase:ResetPasswordForEmail 发重置邮件,用户在邮件链接里设置新密码。

Q4:没有服务器,也不想注册云平台,能做多用户登录吗?

可以用国内免费的网络微数据库服务练习方案三,但只适合学习。要给别人正式使用,账号数据总得存在某个服务上,CloudBase 和 Supabase 都有免费额度,是门槛最低的选择。

总结

方案 推荐度 适合场景
CloudBase 认证 ⭐⭐⭐⭐⭐ 国内用户的正式 App
Supabase 认证 ⭐⭐⭐⭐ 邮箱注册、不想实名认证
网络微数据库 ⭐⭐ 学习原理
文档反馈