Odds client side account authentication and authorization SDK.

Features

OddsHorizon client side account SDK.

Getting started

Add dependency

odds_account_sdk: ^1.0.1-dev.14

Usage

SDK 提供了两种不同的账号认证流程 API

  • 由客户端程序自行处理用户录入的身份凭据进行认证的核心认证流程
  • 通过跳转到账号系统自身的认证页面进行认证的OIDC 标准认证流程

更推荐使用第二种OIDC 标准认证流程,开发工作量更小,安全性也更高, 相比较由客户端自行 开发登录/注册页面以及相应的处理逻辑,可以节约9成的开发时间。

通用初始化流程

导入模块并创建基于 Authing 服务提供方的 OddsAccountClient 实例。

import 'package:odds_account_sdk/client.dart';

final OddsAccountClient client = OddsAccountClient.authing(
    "$userPoolId", "$appId", "$redirectBackUri");

await client.init();

创建 client 实例的参数 userPoolId, appId 和 redirectBackUri 均可以在 Authing 控制台查看。

注意:如果没有在 Authing 控制台修改默认的回调地址,则 redirectBackUri 参数可以不传。

OIDC 标准认证流程 (推荐)

1. 生成认证页面的 URI


final OidcAuthSession session = client.createOidcAuthSession();
final String uri = session.getAuthPageUri();

// navigate this uri with WebView or other web container

2. 根据用户操作身份认证页面后的回调 URI 中的信息换取 token

WebView(
  initialUrl: uri,
  javascriptMode: JavascriptMode.unrestricted,
  gestureNavigationEnabled: true,
  ...,
  onPageFinished: function(String uri) {
    final Result<AuthInfo> result = 
        await session.obtainAuthInfoByRedirectUri(uri);
    
    if (authResult.isSuccess()) {
      final AuthInfo authInfo = result.data;
      currentAccount = authInfo.account;
      accessToken = authInfo.accessToken;
      refreshToken = authInfo.refreshToken;
    }
  }
);

3. 将 accessToken 放置到 grpc 请求的 metadata 中调用后端服务

4. 在 accessToken 过期前,使用 refreshToken 进行更新

final Result<AuthInfo> result = await client.renewToken(refreshToken);

refreshToken 的存活时间一般比较长,所以可以用来刷新存活期较短的 accessToken。 如果在执行 renewToken 时结果返回的 statusCode 为 401,则表示 refreshToken 也过期了, 需要用户重新登录。

更新当前用户账号信息

1. 上传头像

final Result<String> result = 
    await client.uploadAvatar('$avatorImageFilePath');

if (result.isSuccess()) {
  avatarUri = result.data;
}

注意,uploadAvatar 方法只是上传头像文件到账号系统图床,并不会直接替换当前用户头像。

2. 更新账号信息

final Account newProfile = AccountBuilder.clone(currentAccount)
    .withNickname('$newNickname')
    .withPhoto('$newAvatarUri')
    .build();

final Result<Account> result = await client.updateProfile(newProfile);

重置密码

1. 通过短信验证码重置密码(更安全,推荐)

1.1 发送验证短信
final Result<void> = await client.claimPhoneOtp('$phoneNumber');
1.2 等待验证短信发送到手机
1.3 调用接口重置密码
final Result<AuthInfo> result = 
    await client.resetPasswordByPhoneOtp('$phoneNumber', '$otp', '$newPassword');

2. 通过校验旧密码更新新的密码

final Result<AuthInfo> result = 
    await client.resetPassword('$newPassword', '$oldPassword');

3. 直接重置(较不安全,不推荐)

final Result<AuthInfo> result = await client.resetPassword('$newPassword');

退出登录

client.logout();

注意,在采用 OIDC 认证模式下,由于 client.logout 并不能控制 WebView 中的 cookies 状态。 所以,client.logout 只能做到清除 client 对象内部保存的状态,WebView 仍然会保持为已登录, 这就需要开发者手动操作清除 WebView 的 cookies,以确保退出登录行为一致。