概述
Auth Api 提供了一套完整的认证相关功能,支持多种登录方式、用户管理和会话管理。Auth Api 按照功能用途分为 7 个类别。每个类别包含相关的 API 方法,方便开发者根据具体需求快速找到合适的接口。
v3 版本在调用身份认证相关 API 时,使用的是 身份认证 HTTP API 的开放能力。
- 认证登录:用户注册和登录相关的 API 方法,支持多种登录方式。
- 会话管理:管理用户会话状态和令牌的 API 方法。
- 用户管理:获取、更新和管理用户信息的 API 方法。
- 身份源管理:管理第三方身份源绑定和解绑的 API 方法。
- 密码管理:密码重置和修改相关的 API 方法。
- 验证管理:验证码发送、验证和重发相关的 API 方法。
- 其他工具:其他辅助功能的 API 方法。
基础使用示例
- 初始化配置
- 登录 状态检查
- 用户注册流程
- 用户登出
- 密码登录
- 认证状态监听
- 手机验证码登录
Publishable Key 可前往 云开发平台/API Key 配置 中生成
auth.detectSessionInUrl 为初始化可选参数,设置后可以自动检测 URL 中的 OAuth 参数(code、state),适用于signInWithOAuth、linkIdentity等使用场景
import cloudbase from "@cloudbase/js-sdk";
// 初始化
const app = cloudbase.init({
env: "your-env-id", // 替换为您的环境ID
region: "ap-shanghai", // 地域,默认为上海
accessKey: "", // 填入生成的 Publishable Key,
auth: {
detectSessionInUrl: true, // 可选:自动检测 URL 中的 OAuth 参数,适用于signInWithOAuth、linkIdentity
},
});
const auth = app.auth;
// 检查登录状态
async function checkAuthStatus() {
const { data, error } = await auth.getSession();
if (error) {
console.error("检查登录状态失败:", error.message);
return false;
}
if (data.session) {
console.log("用户已登录:", data.session.user);
return true;
} else {
console.log("用户未登录");
return false;
}
}
// 用户注册示例(四步验证流程)
async function registerUser(email, password, verificationCode) {
// 第一步:发送验证码
const { data, error } = await auth.signUp({
email: email,
password: password,
});
if (error) {
console.error("发送验证码失败:", error.message);
return false;
} else {
console.log("验证码已发送,等待验证...");
// 第二步:验证验证码并完成注册
const { data: loginData, error: loginError } = await data.verifyOtp({
token: verificationCode,
});
if (loginError) {
console.error("验证失败:", loginError.message);
return false;
} else {
console.log("注册成功:", loginData.user?.email);
return true;
}
}
}
// 用户登出示例
async function logoutUser() {
const { data, error } = await auth.signOut();
if (error) {
console.error("登出失败:", error.message);
return false;
} else {
console.log("登出成功,会话已清除");
return true;
}
}
// 密码登录示例
async function loginWithPassword(email, password) {
const { data, error } = await auth.signInWithPassword({
email: email,
password: password,
});
if (error) {
console.error("登录失败:", error.message);
return false;
} else {
console.log("登录成功:", data.user?.email);
return true;
}
}
// 监听认证状态变化
auth.onAuthStateChange((event, session, info) => {
console.log("认证状态变化:", event);
switch (event) {
case "INITIAL_SESSION":
console.log("初始会话已建立");
if (session) {
console.log("用户已登录:", session.user);
} else {
console.log("用户未登录");
}
break;
case "SIGNED_IN":
console.log("用户登录成功:", session.user);
break;
case "SIGNED_OUT":
console.log("用户已登出");
break;
case "PASSWORD_RECOVERY":
console.log("密码已重置");
break;
case "TOKEN_REFRESHED":
console.log("令牌已刷新");
break;
case "USER_UPDATED":
console.log("用户信息已更新");
break;
case "BIND_IDENTITY":
console.log("身份源绑定结果");
break;
}
});
// 完整的手机验证码登录页面实现
class PhoneLoginPage {
constructor() {
this.setupEventListeners();
}
// 设置事件监听
setupEventListeners() {
document.getElementById("sendCodeBtn").addEventListener("click", (e) => {
e.preventDefault();
this.sendVerificationCode();
});
document.getElementById("verifyCodeBtn").addEventListener("click", (e) => {
e.preventDefault();
this.verifyCodeAndLogin();
});
}
// 发送验证码
async sendVerificationCode() {
const phone = document.getElementById("phone").value;
if (!phone) {
alert("请输入手机号码");
return;
}
// 验证手机号格式
if (!this.validatePhone(phone)) {
alert("请输入正确的手机号码格式");
return;
}
try {
const { data, error } = await auth.signInWithOtp({
phone: phone,
});
if (error) {
this.handleSendCodeError(error);
} else {
this.handleSendCodeSuccess(data);
}
} catch (error) {
this.handleNetworkError(error);
}
}
// 验证验证码并登录
async verifyCodeAndLogin() {
const code = document.getElementById("code").value;
if (!code) {
alert("请输入验证码");
return;
}
if (!this.verifyFunction) {
alert("请先发送验证码");
return;
}
try {
const { data, error } = await this.verifyFunction({ token: code });
if (error) {
this.handleVerifyError(error);
} else {
this.handleLoginSuccess(data);
}
} catch (error) {
this.handleNetworkError(error);
}
}
// 手机号格式验证
validatePhone(phone) {
const phoneRegex = /^1[3-9]\d{9}$/;
return phoneRegex.test(phone);
}
// 处理发送验证码成功
handleSendCodeSuccess(data) {
this.verifyFunction = data.verifyOtp;
// 显示验证码输入区域
document.getElementById("verificationSection").style.display = "block";
document.getElementById("phoneSection").style.display = "none";
// 开始倒计时
this.startCountdown(60);
document.getElementById("success").innerText =
"验证码已发送到您的手机,请注意查收";
document.getElementById("success").style.display = "block";
}
// 处理发送验证码错误
handleSendCodeError(error) {
console.error("发送验证码失败:", error.code, error.category, error.message);
switch (error.code) {
case "invalid_argument":
console.error(error.message || "手机号格式错误,请检查后重试");
break;
case "not_found":
console.error("该手机号未注册,请先注册或使用其他手机号");
break;
case "resource_exhausted":
console.error("发送频率过高,请稍后再试");
break;
case "unreachable":
console.error("网络连接失败,请检查网络设置");
break;
default:
console.error("发送验证码失败:", error.message);
}
}
// 处理验证错误
handleVerifyError(error) {
console.error("验证失败:", error.code, error.category, error.message);
switch (error.code) {
case "invalid_argument":
// 验证码过期/不正确/不匹配
console.error(error.message || "验证码已过期或不正确,请重新获取");
break;
case "unauthenticated":
// Token 失效,需要重新登录
console.error("登录已过期,请重新登录");
window.location.href = "/login";
break;
case "failed_precondition":
console.error(error.message);
break;
case "not_found":
console.error("用户不存在");
break;
case "unavailable":
console.error("服务暂不可用,请稍后再试");
break;
case "unreachable":
console.error("网络连接失败,请检查网络设置");
break;
default:
console.error("验证失败:", error.message);
}
}
// 处理登录成功
handleLoginSuccess(data) {
document.getElementById("success").innerText = "登录成功!欢迎回来";
document.getElementById("success").style.display = "block";
console.log("用户信息:", data.user);
console.log("会话信息:", data.session);
// 延迟跳转到首页
setTimeout(() => {
window.location.href = "/dashboard";
}, 2000);
}
// 处理网络错误
handleNetworkError(error) {
console.error("网络错误,请检查网络连接后重试:", error);
}
// 开始倒计时
startCountdown(seconds) {
let countdown = seconds;
const btn = document.getElementById("resendBtn");
const originalText = btn.innerText;
btn.disabled = true;
const timer = setInterval(() => {
countdown--;
btn.innerText = `${countdown}秒后可重发`;
if (countdown <= 0) {
clearInterval(timer);
btn.disabled = false;
btn.innerText = originalText;
}
}, 1000);
}
}
// 页面加载完成后初始化
window.addEventListener("DOMContentLoaded", () => {
new PhoneLoginPage();
});
认证登录
signUp
async signUp(params: SignUpReq): Promise<SignUpRes>
注册新用户账户,采用智能注册并登录流程。
手机 号验证码注册 仅支持 上海 地域
- 创建一个新的用户账户
- 采用智能注册并登录流程:发送验证码 → 等待用户输入 → 智能判断用户存在性 → 自动登录或注册并登录
- 如果用户已存在则直接登录,如果用户不存在则注册新用户并自动登录
参数
返回
示例
- 邮箱注册
- 手机号注册
- 注册表单页面实现
- 错误处理
- 验证码验证错误处理
// 第一步:发送邮箱验证码并存储 verificationInfo
const { data, error } = await auth.signUp({
email: "newuser@example.com",
password: "securePassword123",
username: "newuser",
});
if (error) {
console.error("发送验证码失败:", error.message);
} else {
console.log("验证码已发送到邮箱,等待用户输入...");
// 第二步:等待用户输入验证码(通过 Promise 包装用户输入事件)
const verificationCode = "123456"; // 用户输入的验证码
// 第三步:智能验证流程(自动判断用户存在性)
const { data: loginData, error: loginError } = await data.verifyOtp({
token: verificationCode,
});
if (loginError) {
console.error("验证失败:", loginError.message);
} else {
// 第四步:自动完成注册或登录
console.log("操作成功,用户信息:", loginData.user);
console.log("会话信息:", loginData.session);
console.log(
"系统已自动判断:",
loginData.user?.email ? "新用户注册并登录" : "现有用户直接登录"
);
}
}
// 第一步:发送手机验证码
const { data, error } = await auth.signUp({
phone: "13800138000",
password: "mypassword",
});
if (error) {
console.error("发送验证码失败:", error.message);
} else {
console.log("验证码已发送到手机,等待用户输入...");
// 第二步:等待用户输入验证码
const verificationCode = "123456"; // 用户输入的验证码
// 第三步:智能验证流程(自动判断用户存在性)
const { data: loginData, error: loginError } = await data.verifyOtp({
token: verificationCode,
});
if (loginError) {
console.error("操作失败:", loginError.message);
} else {
// 系统自动判断:如果用户已存在则直接登录,如果不存在则注册新用户
if (loginData.user?.phone) {
console.log("现有用户直接登录成功,用户信息:", loginData.user);
} else {
console.log("新用户注册并登录成功,用户ID:", loginData.user?.id);
}
console.log("会话状态:", loginData.session ? "已登录" : "未登录");
}
}
let signUpVerify = null;
async function startRegistration(email, password) {
const { data, error } = await auth.signUp({
email: email,
password: password,
});
if (error) {
console.error("发送验证码失败:", error.code, error.category, error.message);
return false;
} else {
console.log("验证码已发送,系统将自动判断您是注册新用户还是登录现有账户");
signUpVerify = data.verifyOtp;
return true;
}
}
async function completeRegistration(verificationCode) {
if (!signUpVerify) {
console.error("注册流程未开始");
return false;
}
const { data, error } = await signUpVerify({ token: verificationCode });
if (error) {
console.error("验证失败:", error.code, error.category, error.message);
if (error.code === "invalid_argument") {
console.error(error.message || "验证码已过期或不正确,请重新获取");
} else if (error.code === "unauthenticated") {
console.error("认证失效,请重新登录");
window.location.href = "/login";
} else {
console.error("验证失败:", error.message);
}
return false;
} else {
// 智能判断结果反馈
if (data.user?.created_at) {
console.log("新用户注册成功,欢迎加入!");
} else {
console.log("登录成功,欢迎回来!");
}
return true;
}
}
// 注册表单提交
document
.getElementById("registerForm")
.addEventListener("submit", async (e) => {
e.preventDefault();
const email = document.getElementById("email").value;
const password = document.getElementById("password").value;
const nickname = document.getElementById("nickname").value;
await startRegistration(email, password, nickname);
});
// 验证码表单提交
document
.getElementById("verificationForm")
.addEventListener("submit", async (e) => {
e.preventDefault();
const code = document.getElementById("verificationCode").value;
await completeRegistration(code);
});
try {
const { data, error } = await auth.signUp({
email: "existing@example.com",
password: "password123",
});
if (error) {
switch (error.code) {
case "already_exists":
console.error("邮箱/手机号/用户名已被注册,请使用其他邮箱或直接登录");
break;
case "password_too_weak":
console.error("密码强度不足,请使用更复杂的密码");
break;
case "invalid_argument":
console.error("参数格式错误,请检查邮箱或手机号格式");
break;
case "resource_exhausted":
console.error("注册频率过高,请稍后重试");
break;
case "unreachable":
console.error("网络连接失败,请检查网络设置后重试");
break;
default:
console.error("注册失败:", error.message);
}
} else {
console.log("验证码发送成功");
}
} catch (error) {
console.error("网络错误:", error);
}
async function verifyRegistrationCode(code) {
try {
const { data, error } = await signUpCallback(code);
if (error) {
console.error("验证失败:", error.code, error.category, error.message);
switch (error.code) {
case "invalid_argument":
// 验证码过期/不正确/参数缺失
console.error(error.message || "验证码已过期或不正确,请重新获取");
break;
case "failed_precondition":
// 账号已被绑定等业务校验
console.error(error.message);
break;
case "unauthenticated":
// Token 失效,需要重新登录
console.error("认证失效,请重新登录");
window.location.href = "/login";
break;
case "not_found":
// 用户不存在
console.error("用户不存在");
break;
case "unavailable":
// 服务端异常
console.error("服务暂不可用,请稍后再试");
break;
case "unreachable":
console.error("网络连接失败");
break;
default:
console.error("验证失败:", error.message);
}
return false;
} else {
console.log("注册成功");
return true;
}
} catch (error) {
console.error("网络错误:", error);
return false;
}
}
signInAnonymously
async signInAnonymously(params?: SignInAnonymouslyReq): Promise<SignInRes>
匿名登录,创建一个临时匿名用户账户。
- 创建一个临时匿名用户账户
- 无需提供任何身份验证信息
- 适合需要临时访问权限的场景
- 使用前,请确认已在云开发平台/身份认证/注册配置中开启允许匿名登录(默认开启)
参数
返回
示例
- 匿名登录
- 错误处理
- 匿名用户转正流程
// 创建匿名用户
const { data, error } = await auth.signInAnonymously();
if (error) {
console.error("匿名登录失败:", error.message);
console.error("错误代码:", error.code);
} else {
console.log("匿名登录成功");
console.log("匿名用户ID:", data.user?.id);
console.log("会话信息:", data.session);
console.log("是否为匿名用户:", data.user?.is_anonymous);
}
async function safeAnonymousLogin() {
try {
const { data, error } = await auth.signInAnonymously();
if (error) {
switch (error.code) {
case "resource_exhausted":
console.error("请求频率过高,请稍后重试");
break;
case "invalid_provider_token":
console.error("第三方平台令牌无效,请检查令牌格式");
break;
case "provider_not_supported":
console.error("不支持的第三方平台,请检查平台标识");
break;
case "unreachable":
console.error("网络连接失败,请检查网络设置后重试");
break;
case "permission_denied":
console.error("权限不足,请检查安全域名配置");
break;
default:
console.error("匿名登录失败:", error.message);
}
return null;
} else {
console.log("匿名登录成功");
return data;
}
} catch (error) {
console.error("网络错误:", error);
return null;
}
}
// 使用安全登录函数
const result = await safeAnonymousLogin();
if (result) {
console.log("登录成功,用户信息:", result.user);
}
// 第一步:匿名登录
const { data: anonymousData, error: anonymousError } =
await auth.signInAnonymously();
if (anonymousError) {
console.error("匿名登录失败:", anonymousError.message);
} else {
console.log("匿名登录成功,准备升级为正式用户");
// 第二步:绑定邮箱或手机号(示例:绑定邮箱)
const { data: upgradeData, error: upgradeError } = await auth.signUp({
email: "user@example.com",
password: "securePassword123",
anonymous_token: anonymousData.session?.access_token,
});
if (upgradeError) {
console.error("升级失败:", upgradeError.message);
} else {
console.log("升级成功,请输入验证码完成身份验证");
// 第三步:验证验证码
const verificationCode = "123456";
const { data: finalData, error: finalError } = await upgradeData.verifyOtp({
token: verificationCode,
});
if (finalError) {
console.error("验证失败:", finalError.code, finalError.category, finalError.message);
if (finalError.code === "invalid_argument") {
console.error(finalError.message || "验证码已过期或不正确,请重新获取");
} else if (finalError.code === "unauthenticated") {
console.error("认证失效,请重新登录");
} else {
console.error("验证失败:", finalError.message);
}
} else {
console.log("匿名用户成功升级为正式用户");
console.log("新用户信息:", finalData.user);
console.log("是否为匿名用户:", finalData.user?.is_anonymous);
}
}
}
signInWithPassword
async signInWithPassword(params: SignInWithPasswordReq): Promise<SignInRes>
使用用户名、邮箱或手机号和密码登录。
- 支持用户名、邮箱、手机号配合密码三种登录方式(三选一)
- 使用前,请确认已在云开发平台/身份认证/常规登录中开启用户名密码登录(默认开启)
参数
返回
示例
- 用户名登录
- 邮箱登录
- 手机号登录
- 错误处理
const { data, error } = await auth.signInWithPassword({
username: "testuser",
password: "password123",
});
if (error) {
console.error("登录失败:", error.message);
} else {
console.log("登录成功,用户信息:", data.user);
console.log("会话信息:", data.session);
}
const { data, error } = await auth.signInWithPassword({
email: "user@example.com",
password: "mypassword",
});
if (error) {
console.error("登录失败:", error.message);
} else {
console.log("登录成功,用户ID:", data.user?.id);
}
const { data, error } = await auth.signInWithPassword({
phone: "13800138000",
password: "securepassword",
});
if (error) {
console.error("登录失败:", error.code, error.message);
} else {
console.log("登录成功,用户ID:", data.user?.id);
}
try {
const { data, error } = await auth.signInWithPassword({
username: "wronguser",
password: "wrongpassword",
});
if (error) {
// 根据常见错误代码进行完整错误处理
switch (error.code) {
case "not_found":
console.error("用户不存在,请检查用户名/邮箱/手机号是否正确");
break;
case "password_not_set":
console.error("当前用户未设置密码,请使用验证码登录或第三方登录方式");
break;
case "invalid_password":
console.error("密码不正确,请重新输入");
break;
case "user_pending":
console.error("该用户未激活,请联 系管理员激活账户");
break;
case "user_blocked":
console.error("该用户被停用,请联系管理员");
break;
case "invalid_status":
console.error("您已经超过了密码最大重试次数,请稍后重试");
break;
case "invalid_two_factor":
console.error("二次验证码不匹配或已过时,请重新获取");
break;
case "unreachable":
console.error("网络连接失败,请检查网络设置后重试");
break;
default:
console.error("登录失败:", error.message);
}
} else {
console.log("登录成功");
}
} catch (error) {
console.error("网络错误:", error);
}
signInWithOtp
async signInWithOtp(params: SignInWithOtpReq): Promise<SignInWithOtpRes>
使用一次性密码(OTP)进行登录验证,支持邮箱和手机号验证。
短信验证码 仅支持 上海 地域
- 通过邮箱或手机号发送一次性验证码进行登录验证
- 支持完整的验证流程:发送验证码 → 等待用户输入 → 验证并登录
- 适用于无密码登录场景,提供更高的安全性
- 使用前,请确认已在云开发平台/身份认证/登录方式/常规登录中开启邮箱/短信验证码登录
- 如果用户不存在,会默认注册用户,可以通过
shouldCreateUser参数控制是否自动创建用户,默认为 true - 对于邮箱登录,可以通过
emailRedirectTo参数指定回调地址,启用魔法链接(Magic Link)登录,用户点击邮件中的链接即可完成登录
参数
返回
示例
- 手机验证码登录
- 邮箱验证码登录
- 关闭自动注册
- 邮箱魔法链接登录
- 错误处理
const { data, error } = await auth.signInWithOtp({
phone: "13800138000",
});
if (error) {
console.error("发送验证码失败:", error.message);
} else {
console.log("验证码已发送,等待用户输入...");
// 用户输入验证码后验证
const { data: loginData, error: loginError } = await data.verifyOtp({
token: "123456",
});
if (loginError) {
console.error("验证失败:", loginError.message);
} else {
console.log("登录成功:", loginData.user);
console.log("会话信息:", loginData.session);
}
}
// 发送邮箱验证码
const { data, error } = await auth.signInWithOtp({
email: "user@example.com",
});
if (error) {
console.error("发送验证码失败:", error.message);
} else {
console.log("邮箱验证码已发送,请查收邮件...");
// 用户从邮箱获取验证码后验证
const { data: loginData, error: loginError } = await data.verifyOtp({
token: "654321",
});
if (loginError) {
console.error("验证失败:", loginError.message);
} else {
console.log("邮箱登录成功:", loginData.user?.email);
}
}
const { data, error } = await auth.signInWithOtp({
phone: "13800138000",
options: {
shouldCreateUser: false,
},
});
if (error) {
console.error("发送验证码失败:", error.message);
} else {
console.log("验证码已发送,等待用户输入...");
// 用户输入验证码后验证
const { data: loginData, error: loginError } = await data.verifyOtp({
token: "123456",
});
// 未注册用户会提示"user not exist"
}
发送魔法链接:
// 发送魔法链接至邮箱
const { data, error } = await auth.signInWithOtp({
email: "user@example.com",
options: {
emailRedirectTo: "https://example.com/callback",
},
});
if (error) {
console.error("发送魔法链接失败:", error.message);
} else {
console.log("魔法链接已发送至邮箱,请查收邮件并点击链接完成登录");
// 用户点击邮件中的链接后,SDK 会自动完成登录并跳转到 https://example.com/callback
}
在回调页面中获取登录状态:
// 在 emailRedirectTo 指定的回调页面中
// SDK 已自动完成登录,直接获取登录状态即可
import cloudbase from "@cloudbase/js-sdk";
const auth = cloudbase.auth();
// 监听认证状态变化
const { data } = auth.onAuthStateChange((event, session, info) => {
if (event === "SIGNED_IN" && session) {
console.log("登录成功:", session.user);
} else if (event === "SIGNED_OUT") {
console.log("已登出");
}
});
// 取消监听(可选)
// data.subscription.unsubscribe();
// 或者主动获取会话
const { data, error } = await auth.getSession();
if (error) {
console.error("获取会话失败:", error.message);
} else if (data.session) {
console.log("当前用户:", data.session.user);
}
try {
const { data, error } = await auth.signInWithOtp({
phone: "13800138000",
});
if (error) {
switch (error.code) {
case "resource_exhausted":
console.error("发送频率过高,请稍后再试");
break;
case "invalid_argument":
console.error("手机号或邮箱格式错误,请检查后重试");
break;
case "failed_precondition":
console.error("从第三方获取用户信息失败,请重试");
break;
case "aborted":
console.error("尝试次数过多,请返回首页,稍后重试");
break;
case "permission_denied":
console.error("您当前的会话已过期,请返回重试");
break;
case "captcha_required":
console.error("需要输入验证码,请根据反机器人服务接入");
break;
case "captcha_invalid":
console.error("验证码不正确,请根据反机器人服务接入");
break;
case "unreachable":
console.error("网络连接失败,请检查网络设置后重试");
break;
default:
console.error("发送验证码失败:", error.message);
}
return;
}
// 验证验证码
const { data: loginData, error: loginError } = await data.verifyOtp({
token: "123456",
});
if (loginError) {
console.error("验证失败:", loginError.code, loginError.category, loginError.message);
switch (loginError.code) {
case "invalid_argument":
// 验证码过期/不正确/不匹配,提示重新获取
console.error(loginError.message || "验证码已过期或不正确,请重新获取");
break;
case "unauthenticated":
// Token 失效,需要重新登录
console.error("认证失效,请重新登录");
window.location.href = "/login";
break;
case "failed_precondition":
// 账号已被绑定等
console.error(loginError.message);
break;
case "not_found":
console.error("用户不存在");
break;
case "unavailable":
console.error("服务暂不可用,请稍后再试");
break;
default:
console.error("验证失败:", loginError.message);
}
} else {
console.log("登录成功");
}
} catch (error) {
console.error("网络错误:", error);
}
signInWithOAuth
async signInWithOAuth(params: SignInWithOAuthReq): Promise<SignInOAuthRes>
生成第三方平台授权链接,支持微信、Google 等主流平台。
- 生成第三方平台(如微信、Google 等)的授权页面 URL
- 将状态信息保存到浏览器会话中,以便后续验证
- 支持自定义回调地址和状态参数
- 使用前,请确认已在云开发平台/身份认证/登录方式中开启对应的 OAuth 身份源
注意事项
- 调用此方法后,状态信息会自动保存到浏览器会话中,在 cloudbase.init 时设置
auth.detectSessionInUrl为true时,从第三方回调回来后会自动调用 verifyOAuth 进行验证,否则后续需要手动通过 verifyOAuth 方法进行验证 - 如果未提供 state 参数,系统会自动生成格式为
prd-{provider}-{随机字符串}的状态参数 - 回调地址需要配置在云开发平台的安全域名中,否则会返回权限错误
- 目前,使用"微信开放平台"登录时先要确保用户已关联对应的身份源,可以通过 linkIdentity 进行身份源关联
参数
返回
示例
- 微信授权登录
- Google授权登录
- OAuth 登录最佳实践
- 手动处理 OAuth回调(不推荐)
// 初始化
const app = cloudbase.init({
env: "your-env-id", // 替换为您的环境ID
region: "ap-shanghai", // 地域,默认为上海
accessKey: "", // 填入生成的 Publishable Key,
auth: {
detectSessionInUrl: true, // 可选:自动检测 URL 中的 OAuth 参数
},
});
const { data, error } = await auth.signInWithOAuth({
provider: "wechat",
options: {
redirectTo: "https://example.com/callback",
state: "wx_auth_123456",
},
});
if (error) {
console.error("获取微信授权链接失败:", error.message);
} else {
console.log("微信授权链接:", data.url);
console.log("第三方平台:", data.provider);
// 跳转到微信授权页面
window.location.href = data.url;
}
const app = cloudbase.init({
env: "your-env-id", // 替换为您的环境ID
region: "ap-shanghai", // 地域,默认为上海
accessKey: "", // 填入生成的 Publishable Key,
auth: {
detectSessionInUrl: true, // 可选:自动检测 URL 中的 OAuth 参数
},
});
const auth = app.auth;
const { data, error } = await auth.signInWithOAuth({
provider: "google",
});
if (error) {
console.error("获取Google授权链接失败:", error.message);
} else {
console.log("Google授权链接已生成,准备跳转...");
console.log("授权URL:", data.url);
// 在新窗口打开授权页面
window.open(data.url, "_blank");
}
// OAuth登录最佳实践 - 完整的UI交互流程
// 初始化
const app = cloudbase.init({
env: "your-env-id", // 替换为您的环境ID
region: "ap-shanghai", // 地域,默认为上海
accessKey: "", // 填入生成的 Publishable Key,
auth: {
detectSessionInUrl: true, // 可选:自动检测 URL 中的 OAuth 参数,适用于signInWithOAuth、linkIdentity
},
});
// 修改认证状态变化监听器,添加浮窗显示
async function setupAuthStateChangeListener() {
try {
if (!app.auth) return;
// 订阅认证状态变化事件
const { data } = await app.auth.onAuthStateChange(
(event, session, info) => {
console.log("认证状态变化:", { event, session, info });
switch (event) {
case "SIGNED_IN":
if (session && session.user) {
console.log("登录成功!");
}
break;
default:
console.log("未知认证事件:", event);
}
}
);
console.log("认证状态变化监听器已设置");
} catch (error) {
console.error("设置认证状态变化监听器失败:", error);
}
}
class OAuthManager {
constructor() {
this.initEventListeners();
this.provider = "oauth";
}
// 初始化事件监听器
initEventListeners() {
// OAuth登录按钮点击事件
document.getElementById("oauth-login-btn").addEventListener("click", () => {
this.startOAuth();
});
}
// 开始OAuth授权流程
async startOAuth() {
try {
this.showLoading(true);
this.hideError();
const { data, error } = await auth.signInWithOAuth({
provider: this.provider,
});
if (error) {
this.handleOAuthError(error);
} else {
console.log("OAuth授权链接生成成功,正在跳转...");
// 最佳实践:使用当前窗口跳转,保持用户体验
window.location.href = data.url;
}
} catch (error) {
this.handleOAuthError(error);
} finally {
this.showLoading(false);
}
}
showLoading(show) {
document.getElementById("loading").style.display = show ? "block" : "none";
}
}
setupAuthStateChangeListener();
// 初始化OAuth登录管理器
const oAuthManager = new OAuthManager();
// 初始化
const app = cloudbase.init({
env: "your-env-id", // 替换为您的环境ID
region: "ap-shanghai", // 地域,默认为上海
accessKey: "", // 填入生成的 Publishable Key,
});
class OAuthManager {
constructor() {
this.initEventListeners();
this.provider = "oauth";
}
// 初始化事件监听器
initEventListeners() {
// OAuth登录按钮点击事件
document.getElementById("oauth-login-btn").addEventListener("click", () => {
this.startOAuth();
});
// 页面加载时检查是否有OAuth授权回调
document.addEventListener("DOMContentLoaded", () => {
this.checkOAuthCallback();
});
}
// 开始OAuth授权流程
async startOAuth() {
try {
this.showLoading(true);
this.hideError();
const { data, error } = await auth.signInWithOAuth({
provider: this.provider,
});
if (error) {
this.handleOAuthError(error);
} else {
console.log("OAuth授权链接生成成功,正在跳转...");
// 最佳实践:使用当前窗口跳转,保持用户体验
window.location.href = data.url;
}
} catch (error) {
this.handleOAuthError(error);
} finally {
this.showLoading(false);
}
}
// 检查OAuth授权回调
async checkOAuthCallback() {
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get("code");
const state = urlParams.get("state");
if (code && state) {
console.log("检测到OAuth授权回调,正在验证...");
await this.verifyOAuth(code, state);
}
}
// 验证OAuth授权
async verifyOAuth(code, state) {
try {
this.showLoading(true);
const result = await auth.verifyOAuth({
code: code,
state: state,
provider: this.provider,
});
if (result.error) {
this.handleOAuthError(result.error);
} else {
console.log("OAuth登录成功!");
this.showSuccess("OAuth登录成功!");
}
} catch (error) {
this.handleOAuthError(error);
} finally {
this.showLoading(false);
}
}
// 错误处理
handleOAuthError(error) {
console.error("OAuth登录错误:", error);
switch (error.code) {
case "provider_not_supported":
this.showError("不支持的第三方平台,请检查平台标识是否正确");
break;
case "invalid_redirect_uri":
this.showError("回调地址格式错误,请检查URL格式");
break;
case "failed_precondition":
this.showError("从OAuth获取用户信息失败,请检查平台配置");
break;
case "permission_denied":
this.showError("权限不足,请检查安全域名配置");
break;
case "resource_exhausted":
this.showError("请求频率过高,请稍后重试");
break;
case "unreachable":
this.showError("网络连接失败 ,请检查网络设置后重试");
break;
case "invalid_code":
this.showError("授权码无效或已过期,请重新授权");
break;
case "state_mismatch":
this.showError("状态参数不匹配,可能存在安全风险,请重新授权");
break;
default:
this.showError("OAuth登录失败:" + (error.message || "未知错误"));
}
}
showLoading(show) {
document.getElementById("loading").style.display = show ? "block" : "none";
}
showError(message) {
const errorElement = document.getElementById("error-message");
errorElement.textContent = message;
errorElement.style.display = "block";
}
hideError() {
document.getElementById("error-message").style.display = "none";
}
showSuccess(message) {
const successElement = document.getElementById("success-message");
successElement.textContent = message;
successElement.style.display = "block";
}
}
signInWithIdToken
async signInWithIdToken(params: SignInWithIdTokenReq): Promise<SignInRes>
使用第三方平台的身份令牌登录,支持微信、Google 等主流平台。
- 使用第三方平台(如微信、Google 等)的身份令牌进行登录
- 支持指定第三方平台标识,第三方平台需在云开发平台/身份认证/登录方式中先进行配置配置
- 令牌为必填参数
参数
返回
示例
- 微信令牌登录
- Google令牌登录
- 通用令牌登录
- 错误处理
const { data, error } = await auth.signInWithIdToken({
provider: "wechat",
token: "wx_token_1234567890",
});
if (error) {
console.error("微信登录失败:", error.message);
} else {
console.log("微信登录成功,用户信息:", data.user);
console.log("会话信息:", data.session);
}
const { data, error } = await auth.signInWithIdToken({
provider: "google",
token: "google_token_abcdefg",
});
if (error) {
console.error("Google登录失败:", error.message);
} else {
console.log("Google登录成功,用户昵称:", data.user?.user_metadata?.nickName);
}
const { data, error } = await auth.signInWithIdToken({
token: "generic_token_xyz",
});
if (error) {
console.error("令牌登录失败:", error.message);
} else {
console.log("令牌登录成功,用户ID:", data.user?.id);
}
try {
const { data, error } = await auth.signInWithIdToken({
provider: "wechat",
token: "invalid_token",
});
if (error) {
switch (error.code) {
case "invalid_token":
console.error("令牌无效或已过期,请重新获取");
break;
case "provider_not_supported":
console.error("不支持的第三方平台,请使用其他登录方式");
break;
case "failed_precondition":
console.error("从第三方获取用户信息失败,请重试");
break;
case "resource_exhausted":
console.error("尝试过于频繁,请稍后重试");
break;
case "permission_denied":
console.error("权限不足,请检查令牌权限范围");
break;
case "unreachable":
console.error("网络连接失败,请检查网络设置后重试");
break;
default:
console.error("登录失败:", error.message);
}
} else {
console.log("登录成功");
}
} catch (error) {
console.error("网络错误:", error);
}
signInWithCustomTicket
async signInWithCustomTicket(getTickFn: GetCustomSignTicketFn): Promise<SignInRes>
使用自定义登录票据进行登录,支持完全自定义的登录流程。
- 使用自定义的登录票据进行身份验证,登录票据创建可以在服务端使用创建自定义登录票据 API
- 支持传入获取自定义登录票据的函数
- 适用于需要完全自定义登录流程的场景
- 签发 Ticket 详细流程可参考自定义登录
参数
获取自定义登录票据的函数,返回 Promise<string>
返回
示例
- 基本用法
- 异步获取票据
- 错误处理
// 获取自定义登录票据的函数
const getTickFn = () => Promise.resolve("custom_ticket_123456");
const { data, error } = await auth.signInWithCustomTicket(getTickFn);
if (error) {
console.error("自定义登录失败:", error.message);
} else {
console.log("自定义登录成功,用户信息:", data.user);
console.log("会话信息:", data.session);
}
// 异步获取自定义登录票据
const getTickFn = async () => {
// 模拟从后端API获取票据
const response = await fetch("/api/get-custom-ticket");
const data = await response.json();
return data.ticket;
};
const { data, error } = await auth.signInWithCustomTicket(getTickFn);
if (error) {
console.error("自定义登录失败:", error.message);
} else {
console.log("自定义登录成功");
}
try {
const getTickFn = () => Promise.resolve("custom_ticket_123456");
const { data, error } = await auth.signInWithCustomTicket(getTickFn);
if (error) {
switch (error.code) {
case "invalid_ticket":
console.error("票据无效或已过期,请重新获取");
break;
case "ticket_required":
console.error("需要提供自定义登录票据");
break;
case "unreachable":
console.error("网络连接失败,请检查网络设置后重试");
break;
default:
console.error("登录失败:", error.message);
}
} else {
console.log("登录成功");
}
} catch (error) {
console.error("网络错误:", error);
}
signInWithOpenId
async signInWithOpenId(params?: SignInWithOpenIdReq): Promise<SignInRes>
微信小程序 OpenID 静默登录。如果用户不存在,会根据云开发平台/登录方式中对应身份源的登录模式配置,判断是否自动注册。
仅支持在 微信小程序 中使用
参数
登录参数
返回
示例
- 微信云开发模式
- 普通 http 模式
const { data, error } = await auth.signInWithOpenId();
const { data, error } = await auth.signInWithOpenId({ useWxCloud: false });
signInWithPhoneAuth
async signInWithPhoneAuth(params: SignInWithPhoneAuthReq): Promise<SignInRes>
微信小程序手机号授权登录。如果用户不存在,会根据云开发平台/登录方式中对应身份源的登录模式配置,判断是否自动注册。
仅支持在 微信小程序 中使用
参数
登录参数
返回
示例
- 基本用法
const { data, error } = await auth.signInWithPhoneAuth({ phoneCode: "xxx" });
会话管理
getSession
async getSession(): Promise<SignInRes>
获取当前会话信息,检查用户登录状态。
- 获取当前用户的会话信息,包括访问令牌、用户信息等
- 检查用户是否已登录,未登录时返回空会话
参数
无参数
返回
示例
- 检查用户登录状态
- 页面加载时检查登录状态
- 定时检查会话状态
- 错误处理
const { data, error } = await auth.getSession();
if (error) {
console.error("获取会话失败:", error.message);
} else if (data.session) {
console.log("用户已登录:", data.session.user);
console.log("访问令牌:", data.session.access_token);
console.log("过期时间:", data.session.expires_in, "秒");
} else {
console.log("用户未登录,请先登录");
// 显示登录按钮
document.getElementById("loginBtn").style.display = "block";
}
document.addEventListener("DOMContentLoaded", async () => {
const { data, error } = await auth.getSession();
if (error) {
console.error("检查登录状态失败:", error.message);
return;
}
if (data.session) {
// 用户已登录,显示用户信息
document.getElementById("userInfo").innerHTML = `
<p>欢迎,${data.session.user?.name || data.session.user?.username}</p>
`;
document.getElementById("loginBtn").style.display = "none";
document.getElementById("logoutBtn").style.display = "block";
} else {
// 用户未登录,显示登录界面
document.getElementById("loginForm").style.display = "block";
}
});
// 定时检查会话状态,自动刷新令牌
function setupSessionMonitor() {
setInterval(async () => {
const { data, error } = await auth.getSession();
if (error) {
console.error("会话检查失败:", error.message);
} else if (data.session) {
const expiresIn = data.session.expires_in;
// 如果令牌将在5分钟内过期,则自动刷新
if (expiresIn < 300) {
console.log("令牌即将过期,自动刷新...");
await auth.refreshSession();
}
}
}, 60000); // 每分钟检查一次
}
// 启动会话监控
setupSessionMonitor();
try {
const { data, error } = await auth.getSession();
if (error) {
switch (error.code) {
case "unreachable":
console.error("网络连接失败,请检查网络设置后重试");
break;
case "token_expired":
console.error("访问令牌已过期,请重新登录");
// 自动刷新令牌
await auth.refreshSession();
break;
case "invalid_refresh_token":
console.error("刷新令牌无效,请重新登录");
break;
case "refresh_token_expired":
console.error("刷新令牌已过期,请重新登录");
break;
case "user_not_found":
console.error("用户不存在,请重新登录");
break;
case "permission_denied":
console.error("权限不足,请检查安全域名配置");
break;
default:
console.error("获取会话失败:", error.message);
}
} else {
console.log("会话获取成功");
}
} catch (error) {
console.error("未知错误:", error);
}
refreshSession
async refreshSession(refresh_token?: string): Promise<SignInRes>
刷新会话令牌,延长用户登录状态,支持自动续期和错误恢复。
- 使用刷新令牌获取新的访问令牌
- 延长用户会话的有效期
- 支持使用指定的刷新令牌或默认令牌
参数
返回
示例
- 自动刷新会话
- 自定义刷新令牌
- 定时自动刷新
- 错误处理
const { data, error } = await auth.refreshSession();
if (error) {
console.error("刷新会话失败:", error.message);
// 刷新失败,可能需要重新登录
window.location.href = "/login";
} else {
console.log("会话刷新成功,新令牌:", data.session?.access_token);
console.log("新过期时间:", data.session?.expires_in, "秒");
}
const savedRefreshToken = "refresh_token";
if (savedRefreshToken) {
const { data, error } = await auth.refreshSession(savedRefreshToken);
if (error) {
console.error("使用保存的令牌刷新失败:", error.message);
} else {
console.log("使用保存的令牌刷新成功");
}
} else {
console.log("没有保存的刷新令牌,使用默认方式刷新");
const { data, error } = await auth.refreshSession();
if (error) {
console.error("刷新失败:", error.message);
}
}
// 设置定时器,在令牌过期前自动刷新
function setupTokenRefresh() {
setInterval(async () => {
const { data, error } = await auth.getSession();
if (data.session) {
const expiresIn = data.session.expires_in;
// 如果令牌将在5分钟内过期,则刷新
if (expiresIn < 300) {
console.log("令牌即将过期,自动刷新...");
const { data: refreshData, error: refreshError } =
await auth.refreshSession();
if (refreshError) {
console.error("自动刷新失败:", refreshError.message);
} else {
console.log("自动刷新成功");
}
}
}
}, 60000); // 每分钟检查一次
}
// 启动定时刷新
setupTokenRefresh();
try {
const { data, error } = await auth.refreshSession();
if (error) {
switch (error.code) {
case "invalid_refresh_token":
console.error("刷新令牌无效,请重新登录");
// 需要重新登录
window.location.href = "/login";
break;
case "refresh_token_expired":
console.error("刷新令牌已过期,请重新登录");
// 需要重新登录
window.location.href = "/login";
break;
case "user_not_found":
console.error("用户不存在,请重新注册");
// 清除本地会话
localStorage.removeItem("refresh_token");
break;
case "unreachable":
console.error("网络连接失败,请检查网络设置后重试");
break;
case "permission_denied":
console.error("权限不足,请检查安全域名配置");
break;
case "resource_exhausted":
console.error("刷新频率过高,请稍后重试");
break;
default:
console.error("刷新失败:", error.message);
}
} else {
console.log("刷新成功");
}
} catch (error) {
console.error("网络错误:", error);
}
setSession
async setSession(params: SetSessionReq): Promise<SignInRes>
使用现有的访问令牌和刷新令牌来设置用户会话,支持外部系统集成和手动会话管理。
- 使用现有的 access_token 和 refresh_token 来设置用户会话
- 适用于从外部系统获取令牌后手动设置会话的场景
- 成功设置会话后会触发 SIGNED_IN 事件
参数
返回
示例
- 基础会话设置
const { data, error } = await auth.setSession({
access_token: "your_access_token_here",
refresh_token: "your_refresh_token_here",
});
if (error) {
console.error("会话设置失败:", error.message);
} else {
console.log("会话设置成功");
console.log("用户信息:", data.user);
console.log("会话信息:", data.session);
}
signOut
async signOut(params?: SignOutReq): Promise<SignOutRes>
用户登出,清除当前会话和本地存储。
- 安全退出当前用户登录状态
- 清除服务器端会话和本地存储
- 支持重定向到指定页面
- 触发认证状态变化事件
参数
返回
示例
- 基础登出操作
- 登出并重定向
- 安全登出流程
- 错误处理
const { data, error } = await auth.signOut();
if (error) {
console.error("登出失败:", error.message);
} else {
console.log("登出成功");
// 登出后跳转到登录页
window.location.href = "/login";
}
const { data, error } = await auth.signOut({
options: {
redirectTo: "/login",
clearStorage: true,
},
});
if (error) {
console.error("登出失败:", error.message);
} else {
console.log("登出成功,正在跳转到登录页...");
// 自动重定向到登录页
window.location.href = "/login";
}
async function safeSignOut() {
// 显示确认对话框
if (!confirm("确定要退出登录吗?")) {
return;
}
// 显示加载状态
document.getElementById("logoutBtn").disabled = true;
document.getElementById("logoutBtn").innerText = "登出中...";
const { data, error } = await auth.signOut();
if (error) {
console.error("登出失 败:", error.message);
alert("登出失败: " + error.message);
// 恢复按钮状态
document.getElementById("logoutBtn").disabled = false;
document.getElementById("logoutBtn").innerText = "退出登录";
} else {
console.log("登出成功");
// 清除本地存储
localStorage.removeItem("user_session");
sessionStorage.clear();
// 显示成功消息
alert("已安全退出登录");
// 跳转到登录页
window.location.href = "/login";
}
}
// 登出按钮点击事件
document.getElementById("logoutBtn").addEventListener("click", safeSignOut);
try {
const { data, error } = await auth.signOut();
if (error) {
switch (error.code) {
case "unreachable":
console.error("网络连接失败,请检查 网络设置后重试");
alert("网络连接失败,请稍后重试");
break;
case "session_not_found":
console.error("会话不存在,可能已经登出");
// 清除本地存储并跳转
localStorage.clear();
window.location.href = "/login";
break;
case "token_invalid":
console.error("令牌无效,请重新登录");
// 强制清除并跳转
localStorage.clear();
window.location.href = "/login";
break;
case "permission_denied":
console.error("权限不足,无法执行登出操作");
alert("权限不足,无法登出");
break;
case "unreachable":
console.error("服务器连接失败,请检查网络设置");
alert("服务器连接失败,请检查网络");
break;
default:
console.error("登出失败:", error.message);
alert("登出失败: " + error.message);
}
} else {
console.log("登出成功");
// 显示成功消息
alert("已安全退出登录");
// 跳转到登录页
window.location.href = "/login";
}
} catch (error) {
console.error("未知错误:", error);
alert("发生未知错误,请重试");
}
用户管理
getUser
async getUser(): Promise<GetUserRes>
获取当前登录用户的详细信息,包括身份信息、元数据和权限状态,支持用户资料展示和权限验证。
- 获取当前登录用户的完整信息
- 包括用户基本信息、元数据、身份信息等 需要用户已登录状态才能获取完整信息
- 支持检查用户权限和验证状态
参数
无参数
返回
示例
- 基础用户信息获取
- 用户资料页面实现
- 检查用户权限
- 错误处理
const { data, error } = await auth.getUser();
if (error) {
console.error("获取用户信息失败:", error.message);
} else if (data.user) {
const user = data.user;
console.log("用户ID:", user.id);
console.log("邮箱:", user.email);
console.log("手机号:", user.phone);
console.log("用户名:", user.user_metadata?.username);
console.log("昵称:", user.user_metadata?.nickName);
console.log("头像:", user.user_metadata?.avatarUrl);
console.log("注册时间:", user.created_at);
} else {
console.log("用户未登录");
}
// 在用户资料页面显示详细信息
async function loadUserProfile() {
const { data, error } = await auth.getUser();
if (error) {
console.error("获取用户信息失败:", error.code, error.category, error.message);
return;
}
if (data.user) {
const user = data.user;
console.log("用户邮箱:", user.email || "未设置");
console.log("用户手机:", user.phone || "未设置");
console.log("用户名:", user.user_metadata?.name || "未设置");
console.log("昵称:", user.user_metadata?.nickName || "未设置");
console.log("注册时间:", new Date(user.created_at).toLocaleString());
} else {
console.error("用户未登录");
}
}
// 页面加载时调用
loadUserProfile();
async function checkUserPermissions() {
const { data, error } = await auth.getUser();
if (error) {
console.error("获取用户信息失败:", error.message);
return false;
}
if (data.user) {
const user = data.user;
// 检查邮箱是否已验证
if (!user.email_confirmed_at) {
console.log("邮箱未验证,需要验证邮箱");
return false;
}
// 检查用户角色
if (user.role?.includes("administrator")) {
console.log("管理员用户,拥有全部权限");
return true;
} else if (!!user.role?.length) {
console.log("普通用户,拥有基本权限");
return true;
} else {
console.log("未知用户角色");
return false;
}
} else {
console.log("用户未登录,无权限");
return false;
}
}
// 检查权限并执行操作
if (await checkUserPermissions()) {
// 有权限,执行操作
console.log("有权限,继续执行...");
} else {
// 无权限,显示错误
console.log("无权限,操作被拒绝");
}
try {
const { data, error } = await auth.getUser();
if (error) {
switch (error.code) {
case "user_not_found":
console.error("用户不存在,请重新登录");
// 可能是会话已过期,需要重新登录
window.location.href = "/login";
break;
case "token_expired":
console.error("访问令牌已过期,尝试刷新令牌");
// 尝试刷新令牌
await auth.refreshSession();
// 重新获取用户信息
await auth.getUser();
break;
case "unreachable":
console.error("网络连接失败,请检查网络设置后重试");
break;
case "permission_denied":
console.error("权限不足,请检查安全域名配置");
break;
case "invalid_refresh_token":
console.error("刷新令牌无效,请重新登录");
window.location.href = "/login";
break;
case "refresh_token_expired":
console.error("刷新令牌已过期,请重新登录");
window.location.href = "/login";
break;
default:
console.error("获取用户信息失败:", error.message);
}
} else {
console.log("用户信息获取成功");
}
} catch (error) {
console.error("未知错误:", error);
}
refreshUser
async refreshUser(): Promise<CommonRes>
刷新当前登录用户的信息。
- 刷新当前登录用户的完整信息
- 从服务器重新获取最新的用户数据
- 适用于用户信息可能已更新但本地缓存未同步的场景 需要用户已登录状态才能刷新信息
参数
无参数
返回
示例
- 基础刷新
- 用户资料页面刷新
- 错误处理
const { data, error } = await auth.refreshUser();
if (error) {
console.error("刷新用户信息失败:", error.message);
} else {
console.log("用户信息已刷新");
console.log("最新用户信息:", data.user);
console.log("最新会话信息:", data.session);
}
// 当用户修改资料后,刷新页面显示
async function refreshUserProfile() {
const { data, error } = await auth.refreshUser();
if (error) {
console.error("刷新失败:", error.message);
return false;
}
if (data.user) {
const user = data.user;
// 更新页面显示
document.getElementById("userEmail").innerText = user.email || "未设置";
document.getElementById("userPhone").innerText = user.phone || "未设置";
document.getElementById("name").innerText =
user.user_metadata?.name || "未设置";
document.getElementById("userNickname").innerText =
user.user_metadata?.nickName || "未设置";
document.getElementById("userAvatar").src =
user.user_metadata?.avatarUrl || "/default-avatar.png";
console.log("用户信息已刷新并更新显示");
return true;
}
return false;
}
// 在用户修改资料后调用
await refreshUserProfile();
async function safeRefreshUser() {
try {
const { data, error } = await auth.refreshUser();
if (error) {
switch (error.code) {
case "user_not_found":
console.error("用户不存在,请重新登录");
break;
case "token_expired":
console.error("访问令牌已过期,尝试刷新会话");
await auth.refreshSession();
// 重新刷新用户信息
return await auth.refreshUser();
case "unreachable":
console.error("网络连接失败,请检查网络设置后重试");
break;
default:
console.error("刷新用户信息失败:", error.message);
}
return null;
}
return data;
} catch (error) {
console.error("刷新过程中发生未知错误:", error);
return null;
}
}
// 安全地刷新用户信息
const refreshedData = await safeRefreshUser();
if (refreshedData) {
console.log("用户信息刷新成功");
}
updateUser
async updateUser(params: UpdateUserReq): Promise<GetUserRes>
更新当前登录用户的信息。
- 不支持更新密码,更新密码请使用 resetPasswordForEmail 或 resetPasswordForOld 或 reauthenticate
- 更新当前登录用户的基本信息和元数据
- 支持更新邮箱、手机号、用户名、昵称、头像等
- 需要用户已登录状态才能更新信息 更新成功后返回更新后的用户信息
参数
返回
示例
- 基本信息更新
- 邮箱/手机号更新
- 用户资料编辑页面
- 错误处理
const { data, error } = await auth.updateUser({
nickname: "新昵称",
gender: "MALE",
});
if (error) {
console.error("更新用户信息失败:", error.message);
} else {
console.log("用户信息已更新:", data.user);
console.log("新邮箱:", data.user?.email);
console.log("新昵称:", data.user?.user_metadata?.nickName);
}
// 更新 email 或 phone(需要验证)
const { data } = await app.auth.updateUser({
email: "new@example.com",
});
// 调用 verifyOtp 回调验证
await data.verifyOtp({ email: "new@example.com", token: "123456" });
async function saveUserProfile(formData) {
const { data, error } = await auth.updateUser({
username: formData.username,
nickname: formData.nickname,
gender: formData.gender,
description: formData.description,
avatar_url: formData.avatarUrl,
});
if (error) {
console.error("保存失败:", error.code, error.category, error.message);
return false;
} else {
console.log("资料保存成功");
return true;
}
}
// 调用示例
await saveUserProfile({
username: "new_username",
nickname: "新昵称",
gender: "male",
description: "个人简介",
avatarUrl: "https://example.com/avatar.png",
});
try {
// 第一步:更新用户信息(发送验证码阶段)
const { data, error } = await auth.updateUser({
email: "new@example.com",
});
if (error) {
console.error("更新失败:", error.code, error.category, error.message);
switch (error.code) {
case "invalid_argument":
console.error("参数格式错误:", error.message);
break;
case "failed_precondition":
console.error("前置条件不满足:", error.message);
break;
case "resource_exhausted":
console.error("发送频率过高,请稍后再试");
break;
case "unreachable":
console.error("网络连接失败,请检查网络设置后重试");
break;
default:
console.error("更新失败:", error.message);
}
return;
}
// 第二步:如果修改了邮箱/手机号,需要验证码验证(verify 阶段)
if (data.verifyOtp) {
const { data: verifyData, error: verifyError } = await data.verifyOtp({
email: "new@example.com",
token: "123456",
});
if (verifyError) {
console.error("验证失败:", verifyError.code, verifyError.category, verifyError.message);
switch (verifyError.code) {
case "invalid_argument":
// 验证码过期/不正确
console.error(
verifyError.message || "验证码已过期或不正确,请重新获取"
);
break;
case "unauthenticated":
// Token 失效,需要重新登录
console.error("认证失效,请重新登录");
window.location.href = "/login";
break;
case "failed_precondition":
// 该邮箱/手机号已被其他账号绑定
console.error(verifyError.message);
break;
case "not_found":
console.error("用户不存在,请重新登录");
break;
case "unavailable":
console.error("服务暂不可用,请稍后再试");
break;
default:
console.error("验证失败:", verifyError.message);
}
} else {
console.log("邮箱更新成功");
}
} else {
console.log("用户信息更新成功");
}
} catch (error) {
console.error("网络错误:", error);
}
deleteUser
async deleteUser(params: DeleteMeReq): Promise<CommonRes>
删除当前登录用户的账户。
- 永久删除当前登录用户的账户
- 需要验证用户密码进行身份确认
- 删除后所有用户数据将被永久移除
- 操作不可逆,请谨慎使用
参数
返回
示例
- 基础账户删除
- 账户删除确认页面
- 两步验证删除
- 安全删除流程
const { data, error } = await auth.deleteUser({
password: "userPassword123",
});
if (error) {
console.error("账户删除失败:", error.message);
} else {
console.log("账户删除成功");
// 用户已登出,重定向到首页
window.location.href = "/";
}
async function deleteAccount(password) {
if (!confirm("确定要删除账户吗?此操作不可逆,所有数据将被永久删除!")) {
return false;
}
const { data, error } = await auth.deleteUser({ password });
if (error) {
switch (error.code) {
case "invalid_password":
alert("密码错误,请重新输入");
break;
case "user_not_found":
alert("用户不存在");
break;
default:
alert("删除失败: " + error.message);
}
return false;
} else {
alert("账户删除成功");
return true;
}
}
// 删除账户表单提交
document
.getElementById("deleteAccountForm")
.addEventListener("submit", async (e) => {
e.preventDefault();
const password = document.getElementById("password").value;
const success = await deleteAccount(password);
if (success) {
// 重定向到首页
window.location.href = "/";
}
});
async function deleteAccountWithVerification(password, verificationCode) {
// 第一步:验证密码
const { data: verifyData, error: verifyError } = await auth.reauthenticate();
if (verifyError) {
alert("身份验证失败: " + verifyError.message);
return false;
}
// 第二步:等待验证码输入
const { data: updateData, error: updateError } = await verifyData.updateUser({
nonce: verificationCode,
password,
});
if (updateError) {
alert("验证码错误: " + updateError.message);
return false;
}
// 第三步:删除账户
const { data, error } = await auth.deleteUser({ password });
if (error) {
alert("删除失败: " + error.message);
return false;
} else {
alert("账户删除成功");
return true;
}
}
class AccountDeletionManager {
constructor() {
this.deletionAttempts = 0;
this.maxAttempts = 3;
}
async deleteAccount(password) {
if (this.deletionAttempts >= this.maxAttempts) {
alert("删除尝试次数过多,请稍后再试");
return false;
}
this.deletionAttempts++;
const { data, error } = await auth.deleteUser({ password });
if (error) {
if (error.code === "invalid_password") {
const remainingAttempts = this.maxAttempts - this.deletionAttempts;
alert(`密码错误,剩余尝试次数: ${remainingAttempts}`);
} else {
alert("删除失败: " + error.message);
}
return false;
} else {
alert("账户删除成功");
this.deletionAttempts = 0;
return true;
}
}
resetAttempts() {
this.deletionAttempts = 0;
}
}
// 使用账户删除管理器
const deletionManager = new AccountDeletionManager();
// 删除账户
document.getElementById("deleteBtn").addEventListener("click", async () => {
const password = prompt("请输入密码确认删除账户:");
if (password) {
await deletionManager.deleteAccount(password);
}
});
