更新记录

1.0.0(2026-09-30)

第一版提交


平台兼容性

uni-app(5.07)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
√ √ - - - - √ √ -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
- - - - - - - - - - - -

uni-app x(5.15)

Chrome Safari Android iOS 鸿蒙 微信小程序
- - √ √ × -

wb-overseas-login(海外授权登录)

基于 UTS 实现的海外 App 授权登录插件,一套代码同时支持 Android / iOS, 目标是用一个插件收口所有海外登录渠道(LINE / Google / Apple / Facebook …)。

渠道支持情况

渠道 状态 说明
LINE ✅ 已接入 默认策略:优先唤起 LINE App 授权,未安装 LINE 时自动降级为网页(Web)授权
Google ⏳ 规划中 接入后新增 Google* 类型,*不要复用 `Line` 类型**
Apple ⏳ 规划中 同上
Facebook ⏳ 规划中 同上

当前对外 API 仍是 LINE 专用的:login / logout / getAccessToken / refreshAccessToken / verifyAccessToken。 接入第二个渠道时会把入口统一为 login({ provider: 'line' | 'google' | ..., ... }),并保留旧调用方式兼容(provider 缺省即 line)。

新增渠道的落地约定:对外类型集中在 utssdk/interface.uts,各渠道在平台 index.uts 内分发, 不要为每个渠道另起一个插件——登录态缓存、错误码、日志开关都统一由本插件管理。

📖 第一次接 LINE 登录?先看 docs/line-console-setup.md —— 保姆级的 LINE 开发者后台配置手册,含每张页面的标注示意图、每个字段填错的后果、 错误码速查表与配置自检清单。看完再回来看本文件的 API 部分。

  • 插件 ID:wb-overseas-login(与 uni_modules/wb-overseas-login 目录名一致;改名时需同步 package.json 的 id 与所有 import 路径)
  • 命名由来:本插件由 wb-line-login 更名为 wb-overseas-login,为后续多渠道接入预留位置
  • 插件类型:UTS 插件(uts插件 / API插件)
  • 调用方式:import,不使用旧版 uni.requireNativePlugin()

支持平台

运行环境 Android iOS Harmony Web 小程序
uni-app App ✅ ✅ ❌ ❌ ❌
uni-app x App ✅ ✅ ❌ ❌ ❌
  • Android:最低 minSdkVersion 24(Android 7.0)。这是 hard requirement—— LINE Android SDK 5.x 的 aar 自身就声明 minSdkVersion=24,宿主 App 低于 24 会在 processReleaseMainManifest 阶段直接 Manifest merger failed。 宿主侧在 manifest.json → app-plus → distribute → android → minSdkVersion 设置。
  • iOS:最低 deploymentTarget 15.0(LINE iOS SDK 的 Package.swift 声明 .iOS("15.0"))。 宿主侧在 manifest.json → app-plus → distribute → ios → deploymentTarget 设置。
  • 其他平台调用统一返回错误码 9010401 unsupported platform,业务侧请用条件编译降级

iOS 侧的原生桥接文件(不要删)

utssdk/app-ios/ 下有三个 .swift 文件,它们和 UTS 编译进同一个 Swift 模块 unimoduleWbOverseasLogin,UTS 侧直接写类名调用(不需要 import):

文件 解决什么
WbOverseasLoginLoginBridge.swift ① LINE SDK 的 setup() 只能调用一次,第二次会走 Log.assertionFailure(即 Swift.assertionFailure),Debug 构建下直接闪退;② UTS 的 catch 只能拿到 UTSError.message,拿不到真正的 LineSDKError,「用户取消」会被迫退化报 9010204
WbOverseasLoginPermissionBridge.swift UTS 的 Set<T> 在 iOS 上是 UTSSet(NSMutableOrderedSet),与 LINE SDK 要的 Swift 原生 Set<LoginPermission> 不通
WbOverseasLoginURLBridge.swift LINE SDK 的 LoginManager.application(_:open:options:) 带 @MainActor,而 UTS 生成的 Hook 方法是 nonisolated,直接调用会报 actor 隔离错误

维护约定:这三个文件里的形参一律写成 _(UTS 生成的调用不带参数标签), 顶层不要声明与 index.uts 同名的符号。

另外:utssdk/app-ios/index.uts 里不要再出现 LoginManager.shared.setup(...), 初始化幂等已经收敛到 WbOverseasLoginLoginBridge.ensureSetup(_:)。这是线上踩出来的崩溃点。

⚠️ 桥接把错误码以 Int 回调给 UTS,但 LineLoginErrorCode 在 iOS 上被 UTS 翻译成 NSNumber(typealias LineLoginErrorCode = NSNumber)。数字字面量能直接用, Int 变量不能隐式转换 —— 会报 cannot convert value of type 'Int' to expected argument type 'LineLoginErrorCode' (aka 'NSNumber')。 因此 index.uts 里凡是「拿 Int 构造错误对象」的位置,都要走 errorCodeOf(code) (内部就是 NSNumber(value = code))。新增错误码分支时记得沿用这个函数。


依赖的官方 SDK

平台 SDK 版本 配置文件
Android com.linecorp.linesdk:linesdk 5.12.0 utssdk/app-android/config.json
iOS CocoaPods LineSDKSwift(模块名 LineSDK) 5.16.1 utssdk/app-ios/config.json

目录结构

wb-overseas-login
├─ package.json                      插件清单
├─ readme.md                         本文档
├─ docs
│  ├─ line-console-setup.md             📖 LINE 开发者后台配置手册(保姆级)
│  ├─ images/                            手册用的标注示意图(4 张 PNG)
│  └─ tools/gen-console-mockups.py       示意图生成脚本(改文案后重跑即可)
├─ example
│  ├─ overseas-login-demo.vue            uni-app 调用示例
│  └─ overseas-login-demo.uvue           uni-app x 调用示例
└─ utssdk
   ├─ interface.uts                  对外暴露的 API / 类型声明
   ├─ unierror.uts                   错误码与错误对象实现
   ├─ app-android
   │  ├─ index.uts                   Android 实现
   │  ├─ config.json                 gradle 依赖、minSdkVersion
   │  └─ AndroidManifest.xml         权限、Android 11+ queries
   ├─ app-ios
   │  ├─ index.uts                   iOS 实现 + UTSiOSHookProxy
   │  ├─ WbOverseasLoginLoginBridge.swift
   │  │                              原生桥接:幂等 setup + 从 LineSDKError 映射错误码
   │  ├─ WbOverseasLoginPermissionBridge.swift
   │  │                              原生桥接:构造 Set<LoginPermission>
   │  │                              (UTS 的 Set 是 UTSSet,给不了原生 Set)
   │  ├─ WbOverseasLoginURLBridge.swift
   │  │                              原生桥接:在主线程上下文转发 openURL
   │  ├─ config.json                 deploymentTarget、CocoaPods 依赖
   │  └─ Info.plist                  LSApplicationQueriesSchemes
   └─ web
      └─ index.uts                    不支持平台的兜底实现

安装

  1. 把插件目录放到项目的 uni_modules/wb-overseas-login/ 下(或从插件市场安装)。
  2. HBuilderX 中制作自定义基座运行调试。插件依赖三方原生 SDK,标准基座无法运行。
  3. 开发完成后走云打包。
import {
  login,
  logout,
  getAccessToken,
  refreshAccessToken,
  verifyAccessToken,
  isLoggedIn,
  setLogEnabled
} from '@/uni_modules/wb-overseas-login'

⚠️ import 只能引到插件根目录,不要引到 xxx/index.uts 这类内部文件。


前置配置(缺一不可)

📖 这一节只列清单。每一步「在哪点、填什么、填错会怎样」请看 docs/line-console-setup.md(保姆级,带标注图)。

1. LINE Developers Console

  1. 登录 LINE Developers Console 创建 Provider,再创建 LINE Login Channel。 创建时 App types 必须勾 Mobile app —— 不勾就不会出现 iOS / Android 的填写项。
  2. 在 Basic settings 中拿到 Channel ID,即 login() 的 channelId 参数。 (Channel secret 只在服务端换 token 时使用,客户端登录不需要,不要写进 App。)
  3. 在 LINE Login 标签页打开 Use LINE Login in your mobile app,然后登记应用信息:
平台 需要登记 是否必填 位置
Android 包名(applicationId) 必填 LINE Login → Android
Android 签名 SHA-1 可选(填错会报 9010203,清空即可恢复) LINE Login → Android
iOS Bundle ID 必填 LINE Login → iOS
iOS universal link 可选,不用就留空 LINE Login → iOS
  1. Callback URL 只有还要做「网页版登录」(Web app 类型)时才需要填。 App 内的网页授权降级仍然回跳到 line3rdp.<Bundle ID>://authorize,不依赖 Callback URL。
  2. channel 默认是 Developing 状态:只有 Admin / Tester 角色且已绑定 LINE 账号的人能登录。 要对外可用必须 Publish(发布后不可退回)。

自定义基座与正式包的包名 / Bundle ID 可能不同,两者都要登记,否则会出现「登录后不回跳」。

2. URL Scheme(回调必填)

LINE 授权完成后通过 line3rdp.<包名或BundleID> 回跳 App。在 manifest.json 中配置:

{
  "app-plus": {
    "distribute": {
      "android": {
        "schemes": "line3rdp.com.example.dramaplayhouse"
      },
      "ios": {
        "urltypes": "line3rdp.com.example.dramaplayhouse"
      }
    }
  }
}

替换为你的真实 Android 包名 / iOS Bundle ID(两端可以不同)。

3. Android

插件已在 utssdk/app-android/config.json 声明 linesdk 依赖、在 AndroidManifest.xml 声明 INTERNET / ACCESS_NETWORK_STATE 以及 queries(jp.naver.line.android,用于 Android 11+ 检测 LINE 是否安装)。这些配置必须重新打自定义基座才会生效。

4. iOS

插件已在 utssdk/app-ios/config.json 声明 CocoaPods 依赖 LineSDKSwift、在 Info.plist 注入 LSApplicationQueriesSchemes(line、lineauth2)。iOS 的 openURL 回调由 utssdk/app-ios/index.uts 中的 LineAuthHookProxy 转发给 LINE SDK,无需手动改 AppDelegate。


API

所有 API 除 isLoggedIn() 为同步返回外,其余均通过 success / fail / complete 回调返回。

login(options)

发起 LINE 授权登录。

参数 类型 必填 默认 说明
channelId string 否 上次缓存值 LINE Login Channel ID,登录成功后会被缓存,后续调用可不传
scopes string[] 否 ['profile'] 申请权限范围。自动补齐 profile;含 email/address/phone/gender/birthdate/real_name 时自动补 openid
nonce string 否 - OpenID Connect 防重放随机串,需要校验 idToken 时传
onlyLineApp boolean 否 false true 强制 LINE App,未安装则 fail(9010102);false 优先 App,未安装自动降级网页
success function 否 - 成功回调
fail function 否 - 失败回调,返回 errCode / errMsg / errSubject
complete function 否 - 无论成功失败都会调用

success 返回

{
  "errCode": 0,
  "errMsg": "login:ok",
  "userId": "U4af4980629...",
  "displayName": "用户昵称",
  "pictureUrl": "https://profile.line-scdn.net/...",
  "statusMessage": "用户状态签名",
  "accessToken": "eyJhbGciOiJIUzI1NiJ9...",
  "accessTokenExpiresIn": 2591659,
  "idToken": "eyJhbGciOiJIUzI1NiJ9...",
  "scopes": ["profile", "openid"],
  "platform": "android"
}

displayName / pictureUrl / statusMessage 可能为空字符串(用户未设置头像或昵称),此时仍为登录成功。idToken 仅在申请了 openid scope 时才有值。

logout(options)

退出登录,清理本地登录态(Android 清理 profile 与 token,iOS 由 LINE SDK 清除 Keychain)。会保留 channelId,便于下次 login() 不传参。

{ "errCode": 0, "errMsg": "logout:ok" }

getAccessToken(options)

读取当前令牌信息,不发起网络请求。

refreshAccessToken(options)

刷新 access token,成功返回结构与 getAccessToken 一致。

getAccessToken / refreshAccessToken 的 success 返回:

{
  "errCode": 0,
  "errMsg": "getAccessToken:ok",
  "accessToken": "eyJhbGciOiJIUzI1NiJ9...",
  "accessTokenExpiresIn": 2591659,
  "idToken": "eyJhbGciOiJIUzI1NiJ9...",
  "scopes": ["profile", "openid"]
}

verifyAccessToken(options)

校验 access token 是否有效。

参数 类型 必填 说明
accessToken string 否 待校验 token,缺省时使用本地缓存的 token

success 返回:

{
  "errCode": 0,
  "errMsg": "verifyAccessToken:ok",
  "scope": "profile openid",
  "clientId": "1440057261",
  "expiresIn": 2591659
}

Android 通过 LINE 官方接口 GET https://api.line.me/oauth2/v2.1/verify?access_token=... 校验,iOS 使用 LINE SDK 的 API.Auth.verifyAccessToken,两端返回结构一致。

isLoggedIn()

同步返回 boolean,本地判断是否持有登录态(不校验服务端有效性)。

if (isLoggedIn()) {
  // 已有登录态
}

setLogEnabled(enable) / isLogEnabled()

打开 / 关闭插件内部日志(默认关闭),日志前缀 [wb-overseas-login]。


错误码

errCode errMsg 说明
9010001 parameter error 参数错误,如 channelId 为空
9010002 not initialized 未初始化 / 缺少 channelId
9010101 user cancel 用户取消授权
9010102 LINE app is not installed 未安装 LINE,且 onlyLineApp = true
9010103 login is in progress 上一次登录尚未结束
9010201 network error 网络错误
9010202 LINE server error LINE 服务端返回错误
9010203 authentication agent error 授权代理错误(Android AUTHENTICATION_AGENT_ERROR)
9010204 SDK internal error SDK 内部错误
9010301 token not available 无可用 token(未登录)
9010401 unsupported platform 当前平台不支持
9010402 request LINE api failed 请求 LINE 接口失败(verify)

快速使用

import { login, logout, verifyAccessToken, setLogEnabled } from '@/uni_modules/wb-overseas-login'

setLogEnabled(true)

login({
  channelId: '你的 LINE Channel ID',
  scopes: ['profile', 'openid'],
  onlyLineApp: false,
  success: (res) => {
    console.log('login ok', res.userId, res.displayName, res.accessToken)
    verifyAccessToken({
      success: (r) => console.log('token 剩余有效期(秒):', r.expiresIn),
      fail: (e) => console.error(e)
    })
  },
  fail: (err) => {
    if (err.errCode === 9010101) {
      console.log('用户取消了登录')
    } else {
      console.error(err.errCode, err.errMsg)
    }
  }
})

// logout({ success: (r) => console.log(r) })

完整的页面示例见 example/overseas-login-demo.vue(uni-app)与 example/overseas-login-demo.uvue(uni-app x)。


从原生插件 html5app-linelogin 迁移

项 旧原生插件 本 UTS 插件
引用 const plug = uni.requireNativePlugin("html5app-linelogin") import { login } from '@/uni_modules/wb-overseas-login'
调用 plug.login(fn) login({ success, fail, complete })
退出 plug.logout() logout({ success, fail })
成功标识 code === 0 errCode === 0
取消授权 code === 1 fail → errCode 9010101
授权失败 code === -2 fail → 9010201 ~ 9010204
用户昵称 display_name displayName
状态签名 status_message statusMessage
用户 ID user_id userId
用户头像 picture_url pictureUrl
Token accessToken accessToken

字段命名改为小驼峰以符合 UTS 规范。如需与旧代码零改动兼容,可在业务层做一层字段映射。 注意:本插件不返回 refreshToken(iOS 官方 SDK 已不再通过公开 API 暴露 refresh token),刷新请调用 refreshAccessToken()。


常见问题

Q1:登录后不回跳到 App。 检查:① manifest.json 的 Scheme 是否为 line3rdp.<真实包名/Bundle ID>;② LINE Console 登记的包名 / Bundle ID / SHA-1 是否与当前安装包一致;③ 是否使用了自定义基座。

Q2:Android 提示 AUTHENTICATION_AGENT_ERROR(9010203)。 按这个顺序排查(从便宜到麻烦,详见 docs/line-console-setup.md 第 6 节):

  1. 先把后台 Android package signature 整栏清空再试一次 —— LINE 官方给的解法就是这个(该字段本身是可选)。 能登进去 → 就是签名问题。
  2. 用 keytool -printcert -jarfile 你的.apk 取出真实 SHA-1 逐字核对(命令见手册第 6 节)。 注意自定义基座与正式包的签名通常不同,两个都要登记。
  3. 核对后台 Android package name 与安装包一致(改包名后忘了重打基座是常见坑)。
  4. 还不行再考虑 LINE App 版本 / 手机环境问题,可用 onlyLineApp: false 走网页授权验证链路。

Q3:iOS 报 9010202,errMsg 是 NSURLErrorDomain Code=-1200 "TLS错误导致安全连接失败。"。 这是网络问题,不是配置问题。 报错发生在 https://api.line.me/oauth2/v2.1/token(拿授权码换 token 那一步), 与后台登记、scheme、Bundle ID 都无关;-1200 / -9816 是 TLS 握手被中途掐断(常见于代理节点失效或被干扰)。 判断依据与处理办法见 docs/line-console-setup.md 第 10 节。

Q4:iOS 端集成后再编译,提示找不到 UTSiOSHookProxy。 不同 HBuilderX 版本该协议名可能是 UTSHookProxy。若编译报错,把 utssdk/app-ios/index.uts 末尾的 implements UTSiOSHookProxy 改成对应名字即可。Hook 代理类必须写在 index.uts 中,不能写在 vue/uvue 文件里。

Q5:用户昵称或头像为空。 属正常情况(用户未设置),插件会返回空字符串并仍然走 success。

Q6:编译报重复类冲突。 若项目里其他插件也依赖 linesdk,请勿在 app-android/libs 里再手动放 jar/aar,统一用 config.json 的 dependencies 声明,否则云打包会因依赖冲突失败。

Q7:Web / 小程序 / 鸿蒙能用吗? 不能,会返回 9010401,业务侧需做条件编译降级。


更新记录

1.0.0

  • 首次发布:基于 UTS 实现 LINE 授权登录(Android / iOS)
  • 提供 login / logout / getAccessToken / refreshAccessToken / verifyAccessToken / isLoggedIn / setLogEnabled / isLogEnabled
  • 统一错误码,支持 onlyLineApp 强制 App 授权

参考文档

  • LINE 开发者后台配置手册(本插件自带,保姆级):docs/line-console-setup.md
  • LINE 官方开发者平台:https://developers.line.biz/
  • LINE Login API 参考:https://developers.line.biz/en/reference/line-login/#issue-access-token
  • LINE SDK for Android:https://github.com/line/line-sdk-android
  • LINE SDK for iOS Swift:https://github.com/line/line-sdk-ios-swift
  • LINE iOS 接入与后台登记:https://developers.line.biz/en/docs/line-login-sdks/ios-sdk/swift/setting-up-project/
  • LINE iOS 通用链接:https://developers.line.biz/en/docs/line-login-sdks/ios-sdk/swift/universal-links-support/
  • LINE Login channel 起步(发布 / 测试用户):https://developers.line.biz/en/docs/line-login/getting-started/
  • UTS 插件开发文档:https://doc.dcloud.net.cn/uni-app-x/plugin/uts-plugin.html
  • uni_modules 规范:https://uniapp.dcloud.net.cn/plugin/uni_modules.html

隐私、权限声明

1. 本插件需要申请的系统权限列表

  • Android:INTERNET、ACCESS_NETWORK_STATE;并在 Android 11+ 的 queries 中声明 jp.naver.line.android,用于检测 LINE 是否安装。
  • iOS:URL Scheme line3rdp.<BundleID>,以及 LSApplicationQueriesSchemes 白名单 line、lineauth2。

2. 本插件采集的数据、发送的服务器地址及数据用途说明

插件本身不采集任何数据。登录过程中用户的昵称、头像、user_id 等资料与 access token 均由 LINE 官方 SDK 直接返回,插件仅在本地缓存登录态用于判断是否已登录;除校验 token 时请求 LINE 官方接口 *.line.me 外,插件不向任何其他服务器发送数据。

3. 本插件是否包含广告

无。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

Android:INTERNET、ACCESS_NETWORK_STATE,并在 queries 中声明 jp.naver.line.android(Android 11+ 检测 LINE 是否安装);iOS:URL Scheme line3rdp.<BundleID>,白名单 LSApplicationQueriesSchemes 包含 line、lineauth2。

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件本身不采集任何数据。登录过程中用户的昵称、头像、user_id 等资料与 access token 由 LINE 官方 SDK 直接返回,插件仅在本地缓存登录态用于判断是否已登录;插件不向除 LINE 官方接口(*.line.me)以外的任何服务器发送数据。

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

暂无用户评论。