> >

极验一键认证面向开发者快速集成指南

本文用于让开发者在不跳转多份文档的情况下完成极验一键认证(OneLogin)的标准接入。除非需要深度自定义授权页 UI、运营商特殊报备、私有化网络或非标准登录链路,按本文即可完成客户端取号、服务端换取手机号、异常降级和联调验收。

参考来源:

1. 接入目标

OneLogin 适合优化这些登录和注册链路:

  • App 一键认证。
  • H5 一键认证。
  • 微信小程序一键认证。
  • 需要降级到短信验证码、账号密码或其他登录方式的登录场景。

推荐原则:

  • 客户端只负责初始化 SDK、拉起授权页和拿到 tokenprocess_id 等临时凭证。
  • 服务端必须使用 app_key 生成 sign,再调用极验服务端接口换取手机号。
  • 客户端 app_id 必须与服务端签名使用的 app_id 保持一致。
  • app_key 只能放在服务端环境变量、密钥系统或后端配置中心,严禁下发到客户端。
  • process_idtokenaccesscode 都是一次性或短有效期凭证,失败、过期或重复使用时必须重新取号。
  • 网关取号依赖蜂窝数据网络。Wi-Fi、代理、VPN、无 SIM、非三大运营商卡等场景要准备降级登录方式。

2. 标准交互流程

sequenceDiagram
participant U as User
participant C as Client
participant B as Business Server
participant G as GeeTest OneLogin

C->>C: 初始化 SDK / JS,配置 app_id
C->>C: 提前预取号 register / pre_init
U->>C: 点击一键认证
C->>G: 拉起运营商授权页并取号
G-->>C: 返回 process_id、token、authcode/phone 等
C->>B: 提交登录请求 + 取号结果
B->>B: 用 app_key 生成 sign
B->>G: 调用 check_phone
G-->>B: 返回手机号或错误码
B->>B: 手机号成功时创建/登录用户
B-->>C: 返回登录结果;失败时提示降级登录

3. 必要参数

3.1 控制台参数

参数 来源 所在端 用途
app_id 极验后台 客户端、服务端 产品 APPID,客户端初始化和服务端签名都需要
app_key 极验后台 仅服务端 生成服务端 sign,严禁放入客户端
包名 / BundleID / 小程序 ID / 域名报备 极验后台与平台后台 配置侧 用于运营商和极验校验应用身份
IP 白名单 极验后台 服务端出口 IP 服务端请求极验接口时校验来源

3.2 客户端返回给服务端的参数

参数 App 一键认证 H5 一键认证 小程序一键认证 说明
process_id SDK 返回的流水号,一次有效
token 视组件返回 运营商 Token
authcode 条件必填 App 电信新版本接口可能返回,返回时服务端必须透传
auth_code 条件必填 H5 电信可能返回,返回时服务端必须透传
phone 条件必填 视组件返回 H5 联通和电信可能返回,返回时服务端必须透传

3.3 服务端签名参数

sign 生成规则:

timestamp = 当前毫秒级时间戳,13 位
sign_raw = app_id + "&&" + timestamp
sign = HMAC_SHA256_HEX_LOWER(key = app_key, message = sign_raw)

注意:

  • timestamp 必须与请求体里的 timestamp 完全一致。
  • 时间戳单位是毫秒,与极验服务端请求时间误差不能超过 10 分钟。
  • sign 必须是小写 16 进制字符串。

4. 服务端快速接入

4.1 App 一键认证接口

接口地址 https://onelogin.geetest.com/check_phone
请求方式 POST
Content-Type application/json

请求体:

{
"process_id": "SDK 返回的流水号",
"token": "SDK 返回的运营商 Token",
"authcode": "客户端返回的电信校验码,返回时必传",
"timestamp": "当前毫秒级时间戳",
"sign": "服务端生成的签名",
"is_phone_encode": false
}

返回成功示例:

{
"status": 200,
"result": "13888888888",
"charge": true,
"riskflag": "0"
}

处理规则:

  • status === 200result 是手机号:执行业务登录或注册。
  • status !== 200:拒绝一键认证,提示用户重试或切换短信验证码。
  • 电信卡返回 500 时优先检查客户端是否返回并透传了 authcode
  • riskflag === "1" 时按业务风控策略处理,可要求二次验证。

4.2 H5 一键认证接口

接口地址 https://onelogin.geetest.com/web/check_phone
请求方式 POST
Content-Type application/x-www-form-urlencoded

请求字段:

字段 必填 说明
process_id JS SDK 返回的流水号
token JS SDK 返回的运营商 Token
timestamp 当前毫秒级时间戳
sign 服务端生成的签名
phone 条件必填 JS SDK 返回时必须透传
auth_code 条件必填 JS SDK 返回时必须透传

成功示例:

{
"status": 200,
"result": "13888888888",
"success": true,
"charge": true,
"operator": "CM"
}

失败示例:

{
"status": 500,
"result": "get phone failed",
"success": false,
"charge": false,
"operator": "CT"
}

4.3 Node.js 服务端模板

import { createHmac } from "node:crypto";

const GEETEST_ONELOGIN_APP_ID = process.env.GEETEST_ONELOGIN_APP_ID;
const GEETEST_ONELOGIN_APP_KEY = process.env.GEETEST_ONELOGIN_APP_KEY;

function buildOneLoginSign(appId, appKey, timestamp) {
return createHmac("sha256", appKey)
.update(`${appId}&&${timestamp}`)
.digest("hex");
}

async function checkAppOneLogin({ process_id, token, authcode }) {
const timestamp = String(Date.now());
const sign = buildOneLoginSign(
GEETEST_ONELOGIN_APP_ID,
GEETEST_ONELOGIN_APP_KEY,
timestamp
);

const response = await fetch("https://onelogin.geetest.com/check_phone", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
process_id,
token,
authcode,
timestamp,
sign,
is_phone_encode: false
}),
signal: AbortSignal.timeout(3000)
});

if (!response.ok) {
throw new Error(`onelogin http ${response.status}`);
}

return response.json();
}

app.post("/api/onelogin/app", async (req, res) => {
try {
const { process_id, token, authcode } = req.body;
if (!process_id || !token) {
return res.status(400).json({ result: "fail", reason: "missing onelogin params" });
}

const gt = await checkAppOneLogin({ process_id, token, authcode });
if (gt.status !== 200 || !/^1\d{10}$/.test(String(gt.result))) {
return res.status(403).json({
result: "fail",
code: gt.status,
reason: gt.error_msg || gt.result || "onelogin failed"
});
}

// 使用 gt.result 手机号完成登录、注册或绑定。
return res.json({ result: "success", phone: gt.result });
} catch (error) {
return res.status(503).json({
result: "fail",
reason: "onelogin service unavailable"
});
}
});

4.4 服务端安全策略

  • app_key 不进客户端、不进前端构建产物、不进日志。
  • 服务端对 process_idtoken 做必填校验。
  • 服务端只相信极验接口返回的手机号,不相信客户端传入的手机号。
  • 一键认证失败时不要自动创建账号;应降级到短信验证码、密码登录或人工选择方式。
  • 记录 process_idstatuserror_msg、运营商、请求 ID 和服务端出口 IP,便于排查。

5. 全客户端快捷部署

5.1 Android 原生

环境和依赖:

  • Android 5.0 及以上。
  • Gradle 集成推荐:implementation 'com.geetest.android:onelogin:2.9.8'
  • 必要权限包括 INTERNETCHANGE_NETWORK_STATECHANGE_WIFI_STATEACCESS_WIFI_STATEACCESS_NETWORK_STATE
  • READ_PHONE_STATE 为可选权限,建议按合规要求动态申请,可提升取号成功率。

推荐使用进阶模式:

  1. 使用 init() 初始化 SDK 并配置 APPID
  2. 在应用启动、进入登录页前一页或用户登出时调用 register(),SDK 内部会预取号。
  3. 点击一键认证时调用 requestToken() 拉起授权页。
  4. 在成功回调中取得 process_idtokenauthcode 等参数。
  5. 将参数提交到业务服务端,服务端调用 https://onelogin.geetest.com/check_phone
  6. 业务服务端返回登录成功后调用 dismissAuthActivity() 关闭授权页。
  7. 异常或用户切换账号时关闭授权页并降级到其他登录方式。

异常处理:

  • -20102:预取号未完成就取号。进阶模式下分开调用 register()requestToken(),不要紧挨着调用。
  • -20105:预取号或取号超时。检查网络,适当延长 SDK 超时时间。
  • -20106:取号时切换了流量或 SIM。关闭授权页后重新拉起,常规模式需重新预取号。
  • -20200-20201-20202-20203:网络、SIM 或运营商环境不满足。提示打开蜂窝数据或切换登录方式。
  • -20207:Wi-Fi 下切换数据网络失败。检查 CHANGE_NETWORK_STATE 权限和数据网络状态。
  • -20301-20302-20303:用户退出或切换登录方式。按用户选择降级处理。
  • -40101-40201-40301:运营商预取号失败。参考运营商返回码并准备降级。
  • -50100-50101:网络异常或 APPID 与包名/签名不匹配。检查后台配置。

5.2 iOS 原生

环境和依赖:

  • iOS SDK 可通过 CocoaPods 集成,XCFramework 需要 iOS 11+、Xcode 14+。
  • 客户端 APPID 需要与 BundleID 配套,并与服务端签名使用的 app_id 保持一致。

推荐使用 OneLoginPro 进阶模式:

  1. 导入 #import <OneLoginSDK/OneLoginSDK.h>
  2. 应用启动或进入登录页前调用 [OneLoginPro registerWithAppID:GTOneLoginAppId]
  3. 点击一键认证前可调用 [OneLoginPro isPreGetTokenResultValidate],无有效预取号时展示 loading。
  4. 调用 requestTokenWithViewController:viewModel:completion: 拉起授权页。
  5. completion 中读取 process_idtokenauthcode 等字段并提交服务端。
  6. 服务端换号成功后调用 dismissAuthViewController:completion: 关闭授权页。
  7. 用户退出登录后可调用 renewPreGetToken 重新预取号。

核心代码:

#import <OneLoginSDK/OneLoginSDK.h>

- (void)viewDidLoad {
[super viewDidLoad];
[OneLoginPro registerWithAppID:GTOneLoginAppId];
}

- (IBAction)oneLoginAction:(UIButton *)sender {
OLAuthViewModel *viewModel = [OLAuthViewModel new];
if (![OneLoginPro isPreGetTokenResultValidate]) {
// 展示 loading,等待 SDK 内部预取号完成。
}

[OneLoginPro requestTokenWithViewController:self
viewModel:viewModel
completion:^(NSDictionary * _Nullable result) {
// result 中读取 process_id、token、authcode,提交业务服务端。
}];
}

注意:

  • 不要用其他方式关闭授权页,否则可能导致 OneLogin 无法再次调起。
  • 未勾选协议时不要继续取号;如自定义协议流程,可在合规确认后调用 startRequestToken
  • requestToken 成功后 SDK 不再维护预取号结果,用户登出后建议重新预取号。

5.3 HarmonyOS

环境和依赖:

  • 从极验后台下载 HarmonyOS SDK。
  • 工程配置需按文档启用 useNormalizedOHMUrl
  • SDK 已混淆,集成时带上混淆规则,不要再次混淆 SDK。

推荐流程:

  1. 调用 OneLoginHelper.with().init(APPID) 初始化。
  2. 在登录页前一页或应用合适时机调用 register() 预取号。
  3. 点击一键认证时调用 requestToken(context, oneLoginThemeConfig, oneLoginListener)
  4. onResult 中判断 status == 200,读取 process_idtokenauthcode
  5. 将结果提交服务端换取手机号。
  6. 登录完成后调用 stopLoading()dismissAuthPage(uiContext)
  7. 页面关闭或不再使用时调用 removeOneLoginListener(),必要时调用 cancel()

核心代码:

OneLoginHelper
.with()
.setLogEnable(false)
.init(APPID)
.register();

OneLoginHelper.with().requestToken(
getUIContext(),
new OneLoginThemeConfig.Builder().build(),
{
onResult: (jsonObject: Record<string, Object>) => {
if (jsonObject["status"] === 200) {
const processId = jsonObject["process_id"] as string;
const token = jsonObject["token"] as string;
const authCode = jsonObject["authcode"] as string;
// 提交 processId、token、authCode 到服务端。
}
}
}
);

异常处理:

  • -20101:APPID 为空,检查初始化参数。
  • -20102:预取号未完成就取号,给 register() 预留时间。
  • -20200 ~ -20207:网络、SIM、数据流量或权限问题,提示打开蜂窝数据或降级。
  • -30200-50100-50101:网络异常或 APPID 与后台配置不匹配,检查包名/签名/配置。

5.4 H5 一键认证

前置要求:

  • 服务端 https://onelogin.geetest.com/web/check_phone 已对接完成。
  • 页面域名、Referer、Origin 按要求完成报备。
  • 生产页面在 <head> 中添加:
<meta content="always" name="referrer">

步骤:

  1. 页面引用最新版 oneloginh5.js
  2. 页面加载时初始化 GOL,传入 app_idlogoapp
  3. 用户点击一键认证时调用 olInstance.gateway()
  4. onTokenSuccess(data) 中把 process_idtokenphoneauth_code 等字段提交服务端。
  5. 服务端调用 https://onelogin.geetest.com/web/check_phone 换取手机号。
  6. onTokenFail(e) 中按错误码降级到短信验证码或其他登录方式。
  7. 不再使用时调用 olInstance.destory() 销毁实例。

核心代码:

<meta content="always" name="referrer">
<script src="/path/to/oneloginh5.js"></script>
<script>
const olInstance = new GOL({
app_id: "你的 app_id",
timeout: 10000,
logo: "https://example.com/logo.png",
app: "你的应用"
});

olInstance
.onTokenSuccess(async function (data) {
const response = await fetch("/api/onelogin/h5", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data)
});
const result = await response.json();
if (result.result !== "success") {
// 降级到短信验证码。
}
})
.onTokenFail(function (e) {
if (e.code === "30002") {
// 用户点击其他登录方式。
}
olInstance.destory();
});

function startOneLogin() {
olInstance.gateway();
}
</script>

注意:

  • 部分运营商授权页要求用户勾选协议后才能登录,必须使用支持协议勾选的较新 JS。
  • H5 取号依赖网络和报备信息;Wi-Fi、代理、Referer/Origin 不一致时失败率会升高。
  • 错误 3000130002 是用户关闭授权页或切换登录方式,应进入降级登录。

5.5 微信小程序一键认证

前置要求:

  • 个人类型小程序暂不支持一键认证。
  • 服务端部署完成。
  • 下载对应小程序资源,目前一键认证小程序支持微信小程序。
  • 小程序后台申请电信插件,并将极验后台申请的 app_id 和小程序 ID 同步给极验报备审批。
  • 配置 request 合法域名和业务域名,配置生效可能需要约 10 分钟。

步骤:

  1. 在页面 .json 中引入自定义组件:
{
"usingComponents": {
"gt-onelogin": "/component/自定义组件路径/gt-onelogin"
}
}
  1. 在 WXML 使用组件:
<gt-onelogin class="gt-onelogin-container" />
  1. app.json 中引入电信插件:
{
"plugins": {
"myPlugin": {
"version": "1.0.3",
"provider": "wx71a9acc8fcc71c29",
"component": true
}
}
}
  1. 点击一键认证时调用组件:
const child = this.selectComponent(".gt-onelogin-container");
child.getPreWay({
data: {
app_id: "你的 app_id",
authPage: "customer",
agreement_page: "../agreement/index",
logo: "https://example.com/logo.png"
},
success: (params) => {
wx.request({
url: "https://你的域名/api/onelogin/miniapp",
method: "POST",
timeout: 30000,
data: { ...params },
success: (res) => {
if (res.data.result === "success") {
wx.redirectTo({ url: "/pages/success/index" });
} else {
wx.navigateTo({ url: "/pages/sms-login/index" });
}
},
fail: () => {
wx.navigateTo({ url: "/pages/sms-login/index" });
}
});
},
fail: () => {
wx.showToast({ title: "验证失败", icon: "none" });
wx.navigateTo({ url: "/pages/sms-login/index" });
}
});

5.6 React Native

快捷方式:

  1. 使用官方示例 https://github.com/GeeTeam/gt-onelogin-rn-example 作为接入基线。
  2. Native 侧配置 app_id,在登录页前预取号。
  3. 点击一键认证时拉起授权页。
  4. 成功回调中把 process_idtokenauthcode 交给业务服务端。
  5. 服务端换号成功后完成登录;失败时降级到短信验证码。

必须保证:

  • RN 包内不包含 app_key
  • 服务端接口与客户端 app_id 使用同一极验应用。

5.7 Flutter

快捷方式:

  1. 使用官方插件 gt_onelogin_flutter_plugin
  2. pubspec.yaml 可使用 GitHub 或 pub 集成。
  3. 初始化时传入 app_id
  4. 在登录按钮触发时拉起授权页。
  5. 成功回调中提交 process_idtoken 等参数给服务端。
  6. 服务端换号成功后完成登录。

5.8 Uniapp / Unity / WebView App

快捷方式:

  1. Uniapp 使用官方 OneLoginUniappPlugin
  2. Unity 使用官方 gt-onelogin-unity-example
  3. WebView App 可承载 H5 一键认证页,但仍需满足 H5 域名、Referer、Origin 和运营商授权页要求。
  4. 所有端都遵循同一原则:客户端只拿临时凭证,服务端用 app_key 签名换手机号。

6. 必要返回码与处理办法

6.1 App 一键认证服务端返回码

返回码 含义 处理办法
200 请求成功 使用 result 手机号完成登录
500 从运营商获取结果失败 电信卡优先检查 authcode 是否上传;记录 process_id 联系排查
12000 process_id 为空 检查请求体和 JSON 格式
12001 token 为空 检查客户端成功回调是否透传 token
12002 sign 为空 检查服务端签名生成流程
12003 process_id 不为 32 位 使用客户端原样返回的 process_id
12005 时间戳不正确 使用 13 位毫秒时间戳,检查服务器时间
12007 源 IP 不在白名单 检查服务端出口 IP 和极验后台报备
12100 process_id 不存在 重新取号;仍失败检查 SDK 版本
12101 process_id 已使用 重新预取号并获取新凭证
12103 app_id 不正确 检查是否使用 OneLogin 产品 APPID
12104 余额不足 联系商务充值
12105 / 12109 签名错误 检查 HMAC-SHA256、app_idapp_key、毫秒时间戳
12108 / 12200 token 失效 token 有效期约 2 分钟,重新取号
11300 参数不对 对照接口字段逐项检查

6.2 Android 返回码

返回码 含义 处理办法
-20101 APPID 为空 初始化时传入正确 APPID
-20102 预取号未完成就取号 进阶模式分开调用 register()requestToken()
-20105 预取号或取号超时 改善网络或延长超时时间
-20106 取号时切换流量或 SIM 关闭授权页并重新拉起
-20501 context 为空 传入正确 Context
-20503 授权页 UI 配置错误 检查资源、主题配置和 AAR 集成方式
-20200 ~ -20203 网络、SIM、运营商环境不满足 打开蜂窝数据,使用国内三大运营商电话卡
-20207 Wi-Fi 下切换数据网络失败 检查权限和数据网络
-20301 ~ -20303 用户退出或切换登录方式 关闭授权页并降级
-40101 / -40201 / -40301 运营商预取号失败 参考运营商错误码并降级
-50100 / -50101 网络异常或 APPID 与包名签名不匹配 检查网络和后台配置

6.3 H5 一键认证返回码

返回码 含义 处理办法
21002 余额不足 联系商务充值
21003 process_id 为空 检查 form-urlencoded 请求格式
21004 process_id 不存在 重新取号,检查 SDK 版本
21005 process_id 重复使用 重新预取号并获取新凭证
21006 加密时间戳过期 检查服务器时间和 13 位毫秒时间戳
21007 源 IP 不在白名单 检查服务端出口 IP 报备
21008 accesscode 为空 检查客户端返回参数是否完整
22001 sign 参数校验失败 检查签名算法、app_idapp_key
23001 Referer 异常 确认页面 Referer 已报备
23002 Origin 异常 确认页面 Origin 已报备
30001 用户关闭授权页 降级到其他登录方式
30002 用户点击切换其他登录方式 直接进入降级登录
40000 不支持当前运营商 降级到其他登录方式

6.4 小程序返回码

返回码 含义 处理办法
10010 gatconfig 网络请求失败 检查网络、合法域名和超时
10012 gatconfig 返回失败 检查 app_id 是否合法
10030 / 10031 移动获取 token 失败 提供 process_id 查日志,降级登录
10032 移动授权页面校验失败 检查是否本机号码和网络状态
10061 联通取号失败 提供 process_id 查日志,降级登录
10071 / 10072 电信预取号或取号失败 提供 process_id 查日志,降级登录
30002 用户关闭授权页 进入降级登录
40000 不支持当前运营商 进入降级登录

6.5 运营商常见返回码

返回码 运营商 含义 处理办法
103102 移动 包签名错误 检查 APPID、包名、包签名
103111 移动 运营商请求错误,可能代理或判断失败 仅开启数据网络后重试
103511 移动 服务器 IP 白名单失败 联系配置 IP 白名单
103911 移动 token 请求过于频繁 限制 10 分钟内取号频率
104201 移动 token 已失效或重复校验 重启应用或重新取号
200072 移动 CA 根证书校验失败 检查代理、VPN、Wi-Fi 代理
3005 联通 Wi-Fi 网络下取号失败 仅开启数据网络后重试
102001 联通 选择流量通道失败 关闭 Wi-Fi 或开关飞行模式后重试
201001 联通 操作频繁 限制调用频率
-10009 电信 时间戳过期 确认本机时间正确
-10016 电信 安全参数不完整 检查 SDK 返回参数是否完整透传
-8001 / 80001 电信 网络异常或 so 库匹配错误 4G 环境重试并检查 so/abiFilters

7. 联调清单

客户端检查:

  • app_id 是否来自 OneLogin 产品,且与包名、签名、BundleID、小程序 ID 或域名报备一致。
  • 是否提前初始化和预取号,而不是点击按钮后才开始完整初始化。
  • 是否在成功回调中完整透传 process_idtokenauthcodeauth_codephone 等实际返回字段。
  • 是否处理用户关闭授权页、切换其他登录方式、超时、无 SIM、Wi-Fi、代理、VPN 场景。
  • 登录成功后是否按 SDK 要求关闭授权页并释放 listener。

服务端检查:

  • app_key 是否只在服务端读取。
  • sign 是否使用 app_id + "&&" + timestamp 和 HMAC-SHA256 小写 hex。
  • timestamp 是否为 13 位毫秒时间戳,且与签名使用值一致。
  • App 接口是否使用 JSON;H5 接口是否使用 application/x-www-form-urlencoded
  • 服务端出口 IP 是否已加入白名单。
  • 是否只使用极验返回手机号完成登录,不使用客户端传入手机号作为可信手机号。
  • 是否记录 process_id、返回码和降级原因。

上线检查:

  • 已准备短信验证码、账号密码或其他降级登录。
  • 已完成隐私协议展示和用户授权确认。
  • 生产环境关闭 SDK 调试日志。
  • 日志不记录 app_key、完整签名密钥或敏感业务数据。
  • H5 已配置 Referer/Origin;小程序已配置合法域名和业务域名。

8. 常见异常处理

现象 优先检查 解决办法
客户端取号成功但服务端失败 app_id 是否一致、sign 是否正确 检查服务端签名和时间戳
返回 12101 / 21005 process_id 重复使用 重新预取号,不复用旧凭证
返回 token 失效 token 使用间隔过长 token 有效期约 2 分钟,重新取号
H5 报 Referer/Origin 异常 域名报备和 <meta referrer> 完成报备并添加 <meta content="always" name="referrer">
Android Wi-Fi 下失败 数据网络切换权限 添加权限,提示用户开启蜂窝数据
iOS 授权页无法再次拉起 是否用非 SDK 方式关闭授权页 使用 dismissAuthViewController
小程序请求失败 合法域名是否配置生效 补全 request 合法域名并等待生效
电信 App 返回 500 是否透传 authcode 客户端返回 authcode 时服务端必须传入
用户关闭授权页 用户主动取消 降级到短信验证码或其他登录方式