跳转到内容

登录认证

FRVR.auth 把当前玩家在 FRVR 后端做认证 —— 走 FRVR 账号、平台 provider(Facebook、Google Play、Apple……)或匿名登录。

登录是跨设备能力的把关人:云端存储、锦标赛、社交、排行榜、商店 都要走它。

FRVR.config.auth = {};   // 让当前渠道挑自己的 provider

(不需要再调一次 FRVR.init() —— 你已经在启动流程里调过一次了。)

SDK 会按下面顺序自动登录:

  1. 存储里缓存的 token(还没过期),或
  2. 渠道原生凭证(比如 Facebook Instant 会话),或
  3. 匿名登录(如果开启)。
FRVR.config.auth = { enableAnonymousLogin: true };
if (FRVR.auth.isLoggedIn()) {
  const token  = FRVR.auth.getAccessToken();  // JWT,过期则为 null
  const frvrId = FRVR.auth.getFRVRID();       // FRVR user id
}

token 会在大约 60% TTL 时后台自动续 —— 登录状态下 getAccessToken() 你可以认为永远返回新鲜的。

在 Web、frvr.com 和 FRVR 的原生 App 里,宿主有自己的登录界面。一次调用就能打开:

const loggedIn = await FRVR.auth.requestLogin({ reason: 'user' });

玩家登录 FRVR 账号后 resolve true;玩家关掉界面,或渠道没有登录界面时 resolve false。已经有已验证 FRVR 账号的玩家会立刻得到 true。

选项作用
reason请求登录的原因:'user'、'purchase' 或 'titlebar'。宿主可能据此调整界面文案。
method直接打开某种方式:'code'、'password' 或 'oauth'。
provider配合 method: 'oauth',直接进入该 provider:'google'、'apple'、'samsung'。
email预填邮箱。

要决定显示什么,先问渠道支持什么:

const caps = await FRVR.auth.getLoginCapabilities();
// { hostLoginUI: true, methods: ['code', 'password', 'oauth'], providers: ['google', 'apple'] }

if (caps.hostLoginUI) loginButton.onclick = () => FRVR.auth.requestLogin({ reason: 'user' });
if (caps.providers.includes('apple')) showAppleButton();

没有宿主登录界面时,methods 列出游戏可以在页面内自己驱动的方式(渠道允许 FRVR 登录时是 code 和 password),providers 为空。

给自己绘制登录表单的游戏用的免密码流程。玩家会通过邮件收到一次性验证码:

const flow = await FRVR.auth.requestEmailLoginCode('user@example.com');

await flow.continue(codeTypedByPlayer);   // 让玩家登录
await flow.resend();                      // 为同一流程重发验证码

requestEmailRegisterCode(email) 用法相同,并会创建账号。

仅当你自己绘制表单、且渠道不会自动给用户登录时(通常是 Web)才需要:

await FRVR.auth.loginToFRVR({
  platform: 'frvr',
  credentials: {
    email: 'user@example.com',
    password: 'hunter2',
  },
});

或用渠道给你的 provider 凭证:

await FRVR.auth.loginToFRVR({
  platform: 'facebook-instant',
  credentials: {
    asid: '…',
    appId: '…',
    asidSignedRequest: '…',
  },
});

'frvr' 等平台字符串来自 SDK 包导出的 Platform 枚举(Platform.FRVR、Platform.FACEBOOK_INSTANT 等);它们不在 window.FRVR 上,所以这里直接用字符串字面量。

await FRVR.auth.registerOnFRVR(
  { email, password, firstName, lastName },
  /* ifConflictTryLogin = */ true
);

ifConflictTryLogin = true 时,「账号已存在」错误会自动降级为登录尝试。

await FRVR.auth.loginAsAnonymous();

匿名会话仍会保留一个稳定的 ID。之后可以用 registerOnFRVR 把它升级成正式账号。

if (FRVR.auth.isLogoutSupported()) {
  await FRVR.auth.logout();
}

某些渠道不支持登出(玩家始终通过宿主应用登录) —— 先检查再调。

FRVR.auth.addStatusChangeListener((isLoggedIn) => {
  if (isLoggedIn) refreshPlayerUI(FRVR.auth.getFRVRID());
  else            showLoggedOutState();
});

回调只收到一个布尔值。登录和登出时触发;玩家保持登录但账号变了(切换账号,或匿名玩家登录)时也会触发,这时 isLoggedIn 仍为 true,所以要拿 FRVR.auth.getFRVRID() 和上次的值比较。同一账号的 token 续期不会触发,token 过期导致的登出也不会触发。

方法作用
init()自动登录(FRVR.init 会调用)。
isLoggedIn()是否有有效会话?
isLoggingIn()是否正在登录?
getAccessToken()调后端用的 JWT。
getFRVRID()当前用户的 FRVR id。
isVerified()邮箱是否已验证(仅 FRVR 账号)。
getCurrentPlatform()哪个 provider 完成了登录('FRVR'、'facebook'……)。
getAvailableLoginPlatforms()你还能提供的其他 provider。
getLoginCapabilities()当前渠道提供的登录方式和 provider。
requestLogin(options?)打开宿主的登录界面。
requestEmailLoginCode(email) / requestEmailRegisterCode(email)发起邮箱验证码流程。
isFRVRLoginEnabled()当前渠道是否允许 FRVR 账号登录?
loginToFRVR(req)显式登录。
loginAsAnonymous()匿名会话。
registerOnFRVR(creds, ifConflictTryLogin?)创建账号并登录。
logout()清除会话。
isLogoutSupported()当前渠道是否允许登出?
addStatusChangeListener(fn)订阅会话变化。