This package is a UI-free RootAuth API client. Your app owns forms, messages, callbacks, and authorization-code exchange. Native Google sign-in currently supports Android only.
Requires Flutter >= 3.29.0 and Dart >= 3.7.0. Add the dependency to your app's pubspec.yaml, then run flutter pub get:
dependencies:
rootauth_flutter:
git:
url: http://gitlab.standard-software.co/rootauth-public/rootauth-flutter-package.git
ref: main
import 'package:rootauth_flutter/rootauth_flutter.dart';
final auth = RootAuthClient(const RootAuthConfig(
appId: 'your-app-id',
redirectUri: 'https://your-app.example/callback',
));
RootAuthConfig parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
appId |
String |
Yes | None | Application ID; cannot be empty. |
redirectUri |
String |
Yes | None | Registered callback; Google sign-in requires HTTPS. |
apiBaseUrl |
String |
No | https://rootauth-api.rootauth.com |
API URL; must use HTTPS. |
scope |
List<String> |
No | ['openid'] |
OIDC scopes. |
locale |
String |
No | en-US |
Request language, such as zh-CN. |
grantType |
String |
No | authorization_code |
Grant type. |
state |
String |
No | '' |
Callback state. |
RootAuthClient(config, {httpClient, tokenStore, captchaHandler, googleIdentityProvider, urlLauncher}) parameters:
| Parameter | Type | Description |
|---|---|---|
config |
RootAuthConfig |
Required; see above. |
httpClient |
http.Client? |
Optional; the app closes an injected client. |
tokenStore |
TokenStore? |
Optional; defaults to SecureTokenStore(). |
captchaHandler |
CaptchaHandler? |
Optional; required when the server enables captcha. |
googleIdentityProvider |
GoogleIdentityProvider? |
Optional; defaults to the native Android provider. |
urlLauncher |
RootAuthUrlLauncher? |
Optional; type Future<bool> Function(Uri uri, LaunchMode mode). |
JsonMap means Map<String, dynamic>. Keys below are map entries, not Dart named arguments. String | int means either runtime value type; use String for codes with leading zeros.
These shared keys come from config; matching map keys override them. Each method below notes whether it uses shared keys.
| Map key | Type | Default |
|---|---|---|
grant_type |
String |
config.grantType |
redirect_uri |
String |
config.redirectUri |
scope |
List<String> |
config.scope |
state |
String |
config.state |
device_id |
String |
None; the SDK does not generate it |
| Result / error | Fields and types | Description |
|---|---|---|
AuthResponse<T> |
data: T, message: String? |
Successful result. |
RootAuthException |
message: String, statusCode: int?, errorCode: int? |
Thrown on failure; network timeout is 30 seconds. |
| Login callback | redirectUrl: String? |
Regular login does not navigate or exchange tokens. Handle the callback, then call setToken. |
sendCode(params: JsonMap) -> Future<AuthResponse<void>> sends a verification code. Shared keys are optional; other keys:
| Key | Type | Required when / purpose |
|---|---|---|
type |
String |
Optional, default EMAIL; EMAIL, PHONE_TEXT, or WHATSAPP. |
email |
String |
Required for EMAIL. |
email_template_type |
String |
Required for EMAIL: register_code, login_code, reset_pass_code, or login_mfa_code. |
phone_code, phone_num |
String, String |
Required for PHONE_TEXT / WHATSAPP; calling code excludes +. |
phone_text_template_type |
String |
Required for PHONE_TEXT; same template values as email. |
mfa_token |
String |
Required for template login_mfa_code. |
login(params: JsonMap) -> Future<AuthResponse<LoginResult>> requires type: String and these keys:
type |
Required map keys and types |
|---|---|
EMAIL_PASS |
email: String, password: String |
EMAIL_CODE |
email: String, code: String | int |
PHONE_PASS |
phone_code: String, phone_num: String, password: String |
PHONE_CODE |
phone_code: String, phone_num: String, code: String | int |
USER_NAME_PASS |
user_name: String, password: String |
WHATSAPP_CODE |
phone_code: String, phone_num: String, code: String | int |
Additional login key / result |
Type | Description |
|---|---|---|
is_invite, invite_auto_register |
int, int |
Optional; each is 0/1. |
password |
String |
Pass plaintext; encrypted if an RSA public key is configured. |
redirectUrl |
String? |
Successful callback URL. |
mfaToken |
String? |
MFA challenge token. |
mfaMethods |
List<String> |
Available verification methods. |
requiresMfa |
bool |
Whether MFA is required. |
final result = await auth.login({
'type': 'EMAIL_PASS',
'email': 'user@example.com',
'password': 'password',
});
if (result.data.requiresMfa) {
// Pass result.data.mfaToken to verifyLoginMfa.
} else {
// Handle result.data.redirectUrl in the app.
}
verifyLoginMfa(params: JsonMap) -> Future<AuthResponse<JsonMap>> completes MFA. Shared keys are optional:
| Key | Type | Required when |
|---|---|---|
mfa_token |
String |
Always; from login. |
mfa_type |
String |
Always: EMAIL, EMAIL_BIND, PHONE_CODE, PHONE_CODE_BIND, TOTP, or TOTP_BIND. |
code |
String | int |
Always; email, SMS, or TOTP code. |
email |
String |
EMAIL_BIND. |
phone_code, phone_num |
String, String |
PHONE_CODE_BIND. |
totp_bind_code |
String | int |
TOTP_BIND when prior email/phone verification is required. |
Returned data is the raw server map and may contain redirect_url: String; the app handles it.
register(params: JsonMap) -> Future<AuthResponse<JsonMap>>: type: String is optional. Without it, nonempty phone fields select phone registration; otherwise email registration is used:
type |
Required map keys and types |
|---|---|
EMAIL_CODE_PASS (default) |
email: String, code: String | int, password: String |
PHONE_CODE_PASS (phone default) |
phone_code: String, phone_num: String, code: String | int, password: String |
USER_NAME_PASS |
user_name: String, password: String |
WHATSAPP_CODE |
phone_code: String, phone_num: String, code: String | int |
Shared keys are optional. password follows the same RSA rule as login; successful data may contain redirect_url: String.
verifyResetPasswordCode(params: JsonMap) -> Future<AuthResponse<String>> checks a reset code; data is verify_token. Shared keys are not added automatically.
| Key | Type | Required when |
|---|---|---|
type |
String |
Always: EMAIL_CODE or PHONE_CODE. |
email |
String |
EMAIL_CODE. |
phone_code, phone_num |
String, String |
PHONE_CODE. |
code |
String | int |
Always. |
The SDK fixes scene: String to reset_pass_code.
resetPassword(params: JsonMap) -> Future<AuthResponse<void>> sets a new password. Shared keys are optional.
| Key | Type | Required when |
|---|---|---|
type |
String |
Optional: EMAIL_CODE or PHONE_CODE; inferred from phone fields by default. |
email |
String |
EMAIL_CODE. |
phone_code, phone_num |
String, String |
PHONE_CODE. |
password, password_confirmation |
String, String |
Both required; encrypted if an RSA key is configured. |
code |
String | int |
If verify_token is absent. |
verify_token |
String |
If code is absent; from verifyResetPasswordCode. |
updateProfile(params: JsonMap) -> Future<AuthResponse<void>> changes the supplied fields. Shared keys are not added automatically.
| Map key | Type | Purpose |
|---|---|---|
user_name |
String |
New username. |
password_old |
String |
Old password when changing passwords. |
password |
String |
New password when changing passwords. |
The SDK encrypts both password fields if an RSA public key is configured.
getUserInfo(params: JsonMap) -> Future<AuthResponse<JsonMap>> returns the raw server map.
| Map key | Type | Required / default |
|---|---|---|
response_type |
String |
Required; use the server-configured value. |
redirect_uri |
String |
Optional; defaults to config.redirectUri. |
scope |
List<String> |
Optional; defaults to config.scope. |
state |
String |
Optional; defaults to config.state. |
grant_type |
String |
Optional; defaults to config.grantType. |
device_id |
String |
Optional; the SDK does not generate it. |
| Method | Parameters and types | Result / behavior |
|---|---|---|
signInWithGoogle({String? state}) |
Optional state: String?, default config.state. |
Future<RootAuthAuthorizationGrant>; native Android account selection, no callback navigation. |
startThirdPartyLogin(String authBy, {JsonMap params = const {}}) |
Required authBy: String; optional params: JsonMap, see next table. |
Future<Uri>; Google returns a callback URI; other providers open a browser and return an authorization URI. |
getThirdPartyQrAuthorize([JsonMap params = const {}]) |
Optional params: JsonMap, see next table. |
Future<AuthResponse<JsonMap>>; gets a WeChat service-account QR code. |
getThirdPartyQrResult(String stateKey) |
Required stateKey: String. |
Future<AuthResponse<JsonMap>>; one QR-status query. |
| API | Parameters / fields and types | Description |
|---|---|---|
signInWithGoogle |
state: String? |
Overrides config.state; iOS throws UnsupportedError. |
RootAuthAuthorizationGrant |
code: String, state: String, callbackUri: Uri |
Exchange code through your backend; it is not an access token. |
startThirdPartyLogin |
authBy: String |
Examples: google_oauth, telegram, facebook, vkid; availability depends on the server. |
startThirdPartyLogin.params |
JsonMap |
Accepts section 3 shared keys; Google can override state: String and redirect_uri: String. For other providers, auth_by: String is fixed to authBy and response_type: String to code. |
getThirdPartyQrAuthorize.params |
JsonMap |
Accepts shared keys and auth_by: String, default wechat_service. |
QR authorization data |
qr_url: String?, authorize_url: String?, state_key: String | int, expire_seconds: int? |
Display the QR code; query with state_key.toString(). |
QR result data |
status: String, redirect_url: String? |
The app handles polling, expiry, and callbacks. |
Native Google sign-in needs a Web OAuth client and Android OAuth clients for the app package/signing SHA-1 combinations in one Google Cloud project. The server supplies the Web client ID.
| Method | Parameters and types | Result / description |
|---|---|---|
getAppConfig({bool refresh = false}) |
Optional refresh: bool; true forces a refresh. |
Future<JsonMap>; gets app settings, cached by default. |
getToken() |
None | Future<String?>; reads this app's token. |
setToken(String token) |
Required nonempty token: String. |
Future<void>; stores the access token obtained by your backend. |
isAuthenticated() |
None | Future<bool>; only checks for a nonempty local token. |
logout() |
None | Future<void>; removes the local token only. |
dispose() |
None | void; closes the SDK-owned HTTP client. |
| Extension API | Parameters and types | Result / description |
|---|---|---|
CaptchaHandler.verify |
Required appConfig: JsonMap, captchaConfig: JsonMap, purpose: String, locale: String |
Future<CaptchaTicket>; purpose is send-code or submit. |
CaptchaTicket |
Required ticket: String; optional randStr: String? |
Use a fresh ticket per request; randStr is for Tencent captcha. |
TokenStore.read |
key: String |
Future<String?>; reads a token. |
TokenStore.write |
key: String, value: String |
Future<void>; stores a token. |
TokenStore.delete |
key: String |
Future<void>; deletes a token. |
GoogleIdentityProvider.signIn |
Required serverClientId: String |
Future<String?>; returns a Google ID token or null on cancellation. |
mapGoogleSignInException |
error: GoogleSignInException |
Returns RootAuthGoogleException. |
mapGooglePlatformException |
error: PlatformException |
Returns RootAuthGoogleException. |
RootAuthGoogleException.kind |
GoogleAuthErrorKind |
canceled, network, configuration, unavailable, inProgress, failed. |
| Rule | Description |
|---|---|
| Captcha | When enabled, sendCode, login, register, verifyResetPasswordCode, and resetPassword need a CaptchaHandler. |
| Token storage | Default: SecureTokenStore([FlutterSecureStorage? storage]); key: rootauth.<appId>.accessToken. |
| Expired session | HTTP 401 or business error code 1010 clears the local token. |
| HTTP client | The app closes an injected client. |