更新记录

0.0.1(2026-04-10) 下载此版本

新增飞书鉴权登录插件


平台兼容性

uni-app(4.14)

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

cnd-feishu-auth

飞书鉴权登录 UTS 原生插件,基于飞书官方 LarkSSO SDK 实现,支持 Android 和 iOS 双端。

拉起飞书 App 完成 SSO 授权登录,获取 authorization code,可用于后端换取 user_access_token 获取用户信息。

功能特性

  • 调用飞书原生SDK 拉起飞书 App 进行 SSO 授权
  • 支持 PKCE 挑战码模式(useChallengeCode),可选开启
  • 支持自定义 scope 权限范围
  • 支持检测飞书是否已安装
  • 完善的错误码体系,覆盖用户取消、参数错误、未安装等场景

环境要求

平台 最低版本
Android minSdkVersion 21 (Android 5.0)
iOS deploymentTarget 12.0

暴露的 API

插件对外导出 3 个方法

import {
  sendFeishuAuth,
  isFeishuInstalled,
  handleFeishuOpenURL
} from "@/uni_modules/cnd-feishu-auth"

1. sendFeishuAuth(options)

发起飞书授权登录。调用后会拉起飞书 App,用户确认授权后通过回调返回 code

参数 options 类型:FeishuLoginOptions

属性 类型 必填 默认值 说明
appId string - 飞书开放平台的 App ID,如 "cli_xxxxxxxxxx"
scope string[] [] 权限范围数组,如 ["contact:user.id:readonly"]。不传则使用应用默认权限
useChallengeCode boolean true 是否开启 PKCE 挑战码模式。开启后回调中会包含 codeVerifier
success (result: FeishuLoginResult) => void - 授权成功回调
fail (error: FeishuLoginError) => void - 授权失败回调
complete () => void - 授权完成回调(无论成功失败都会调用)

成功回调 result 类型:FeishuLoginResult

属性 类型 说明
code string 飞书授权码,有效期 5 分钟,且只能使用一次
codeVerifier string PKCE 挑战码。仅 useChallengeCode = true 时有值

失败回调 error 类型:FeishuLoginError

属性 类型 说明
errCode number 错误码,见下方错误码表
errMsg string 错误描述信息

2. isFeishuInstalled()

检测飞书是否已安装。

返回值类型:IsFeishuInstalledResult

属性 类型 说明
installed boolean true 表示飞书已安装

注意:iOS 端需要在 manifest.json 中配置 LSApplicationQueriesSchemes 包含 "lark",否则始终返回 false

3. handleFeishuOpenURL(url)

处理飞书 SSO 回调 URL。需要在 App.vue 中调用,将飞书授权完成后跳回 App 的 URL 传给 SDK 解析。

参数 类型 说明
url string 飞书回调的完整 URL 字符串

返回值booleantrue 表示该 URL 已被 SDK 成功处理。

注意:Android 端新架构下,飞书回调由 FeishuCallbackActivity 直接处理,不再经过 App.vuenewintent 事件。此方法在 Android 端作为兜底保留,iOS 端仍需调用。

错误码

错误码 常量名 说明
0 FEISHU_SUCCESS 成功
20001 FEISHU_NOT_INSTALLED 飞书未安装(无法跳转飞书)
20002 FEISHU_USER_CANCEL 用户取消了授权
20003 FEISHU_AUTH_FAILED 飞书授权失败
20004 FEISHU_INVALID_PARAMS 参数错误(如 appId 为空)
20005 FEISHU_SDK_INIT_FAILED SDK 初始化或发送请求失败
20006 FEISHU_BAD_STATE state 校验失败
20007 FEISHU_NO_VALID_CODE 未获取到有效凭证
20099 FEISHU_UNKNOWN 未知错误

接入步骤

第一步:配置 manifest.json

打开项目根目录的 manifest.json,配置 URL Scheme 和白名单。

关键规则

  • Android 的 scheme 为 App ID 原值(带下划线),如 cli_axxxxxxxxx
  • iOS 的 scheme 为 App ID 去掉下划线,如 cli_axxxxxxxxx
  • 两端的 scheme 格式不同,这是飞书 SDK 的设计,不要搞混

请将以下示例中的 cli_axxxxxxxxx 替换为你自己的 App ID:

{
  "app-plus": {
    "distribute": {
      "android": {
        "schemes": "cli_axxxxxxxxx"
      },
      "ios": {
        "urltypes": [
          {
            "urlschemes": ["cli_axxxxxxxxx"]
          }
        ],
        "urlschemewhitelist": "lark",
        "LSApplicationQueriesSchemes": ["lark"]
      }
    }
  }
}
配置项 平台 作用
android.schemes Android 注册 URL Scheme,飞书授权后跳回 App
ios.urltypes[].urlschemes iOS 注册 URL Scheme,飞书授权后跳回 App
ios.urlschemewhitelist iOS 允许查询的 scheme 白名单
ios.LSApplicationQueriesSchemes iOS 允许检测飞书是否安装(canOpenURL

如果你的项目同时使用了其他插件(如企业微信),schemes 之间用逗号分隔:

"schemes": "cli_axxxxxxxxx,wxxxxxxxx"

第二步:修改插件内 AndroidManifest.xml 的 scheme(Android 必须)

插件内的 utssdk/app-android/AndroidManifest.xml 中,FeishuCallbackActivity 的 intent-filter scheme 是硬编码的示例值。你需要将其替换为你自己的 App ID:

打开 uni_modules/cnd-feishu-auth/utssdk/app-android/AndroidManifest.xml,找到:

<data android:scheme="cli_axxxxxxxxx" />

替换为你的 App ID(保持带下划线的格式):

<data android:scheme="你的_App_ID" />

为什么需要这一步? Android 端飞书授权后,飞书 App 通过 URL Scheme 跳回你的 App。FeishuCallbackActivity 注册的 scheme 必须与你的 App ID 一致,否则飞书回调无法路由到此 Activity,导致授权完成后无响应。

如果还是无法授权 请直接将以下代码复制一份到你的项目根目录,改名为 AndriodMainfest.xml,将cli_xxxxx 改成你的飞书项目 ID

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="io.dcloud.nativeresouce">

    <application>
        <activity
            android:name="io.dcloud.PandoraEntryActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="cli_xxxxx" />
            </intent-filter>
        </activity>
    </application>

</manifest>

第五步:配置 App.vue

飞书授权完成后,飞书会通过 URL Scheme 跳回你的 App。你需要在 App.vue 中捕获回调 URL 并传给插件处理。

重要newintent 事件中需要加 setTimeout 延迟(建议 100ms),确保系统已经更新完 plus.runtime.arguments

<script>
  // #ifdef APP-PLUS
  import { handleFeishuOpenURL } from "@/uni_modules/cnd-feishu-auth"
  // #endif

  export default {
    onLaunch: function () {
      // #ifdef APP-PLUS
      // 处理冷启动时的 URL Scheme
      this.handleSchemeUrl()

      // 监听热启动时的 URL Scheme(从飞书跳回)
      var self = this
      plus.globalEvent.addEventListener("newintent", function () {
        setTimeout(function () {
          self.handleSchemeUrl()
        }, 100)
      })
      // #endif
    },
    methods: {
      // #ifdef APP-PLUS
      handleSchemeUrl: function () {
        var args = plus.runtime.arguments
        if (!args) return

        // 飞书 SSO 回调处理
        // Android scheme: cli_xxx://...  iOS scheme: clixxx://...
        if (args.indexOf("cli") === 0) {
          console.log("飞书 SSO 回调 URL:", args)
          handleFeishuOpenURL(args)
          plus.runtime.arguments = ""
          return
        }

        plus.runtime.arguments = ""
      }
      // #endif
    }
  }
</script>

第六步:调用授权 API

// #ifdef APP-PLUS
import {
  sendFeishuAuth,
  isFeishuInstalled
} from "@/uni_modules/cnd-feishu-auth"
// #endif

// 检测飞书安装状态
var result = isFeishuInstalled()
console.log("飞书已安装:", result.installed)

// 发起授权(普通模式)
sendFeishuAuth({
  appId: "cli_xxxxxxxxxx",
  scope: ["contact:user.id:readonly"],
  useChallengeCode: false,
  success: function (res) {
    console.log("授权码:", res.code)
    // 将 code 发送给后端换取 user_access_token
  },
  fail: function (err) {
    console.error("授权失败:", err.errCode, err.errMsg)
  }
})

第七步(可选):PKCE 挑战码模式

PKCE 模式允许客户端直接用 code + codeVerifier 换取 Token,无需 app_secret

sendFeishuAuth({
  appId: "cli_xxxxxxxxxx",
  scope: ["contact:user.id:readonly"],
  useChallengeCode: true,
  success: function (res) {
    console.log("code:", res.code)
    console.log("codeVerifier:", res.codeVerifier)

    // PKCE 模式换取 token
    uni.request({
      url: "https://xxxxxxxxxx", //你自己的后端地址
      method: "POST",
      header: { "Content-Type": "application/json" },
      data: {
        grant_type: "authorization_code",
        client_id: "cli_xxxxxxx",
        code: res.code,
        code_verifier: res.codeVerifier
      },
      success: function (tokenRes) {
        console.log("access_token:", tokenRes.data.access_token)
      }
    })
  }
})

重要注意事项

1. Android 回调机制(必读)

Android 端使用了独立的 FeishuCallbackActivity 架构来解决 uni-app 主 Activity 回调丢失问题:

  • 问题背景:uni-app 的主 Activity (PandoraEntryActivity) 是 singleTask 模式,飞书 SDK 回调时走 onNewIntent,但 HBuilderX 框架不会将 onNewIntent 的数据同步到 plus.runtime.arguments,导致回调数据丢失。
  • 解决方案:插件内置了 FeishuCallbackActivitysingleTop + exported=true),作为 SDK 的 context 和回调接收者。飞书 App 直接回调到这个 Activity,绕过了 PandoraEntryActivity 的问题。
  • 对使用者的影响:Android 端授权回调是自动处理的,不依赖 App.vue 中的 handleFeishuOpenURL。但仍建议保留 App.vue 中的调用作为兜底。

2. Android 根目录 AndroidManifest.xml(通常不需要)

插件已内置 FeishuCallbackActivity 专门处理飞书回调(见第四步),因此正常情况下不需要在项目根目录添加 AndroidManifest.xml

历史背景:早期方案曾在根目录 AndroidManifest.xml 中给 PandoraEntryActivity 注册飞书 scheme 的 intent-filter。这是因为当时没有独立的回调 Activity,需要主 Activity 来接收回调。现在有了 FeishuCallbackActivity,这个配置已不再需要。如果你的项目根目录有这样的遗留配置,可以保留(不影响功能),也可以删除以避免混淆。

仅当以下情况才需要考虑根目录 AndroidManifest.xml

  • 遇到 Permission Denial 错误,需要将 PandoraEntryActivity 设为 exported=true
  • 某些特殊 HBuilderX 版本的打包行为不会合并插件内的 manifest

3. iOS 端 scheme 去掉下划线

这是最容易出错的地方。飞书 iOS SDK 会自动将 App ID 中的下划线去掉作为 URL Scheme:

App ID Android Scheme iOS Scheme
cli_axxxxxxxxxxxx cli_axxxxxxxxxxxx cliaxxxxxxxxxxx

如果 iOS 的 urltypes 配置了带下划线的 scheme,飞书授权后将无法跳回 App。

4. iOS LSApplicationQueriesSchemes 必须配置

iOS 9+ 系统要求声明 LSApplicationQueriesSchemes 才能使用 canOpenURL 检测其他 App 是否安装。如果不配置:

  • isFeishuInstalled() 始终返回 false
"ios": {
    "LSApplicationQueriesSchemes": ["lark"]
}

5. code 有效期和一次性使用

飞书返回的 authorization code 有以下限制:

  • 有效期 5 分钟
  • 只能使用一次(换取 token 后立即失效)

如果你在调试时反复用同一个 code 换 token,会收到 invalid_grant 错误。每次测试需要重新发起授权。

6. Android queries 声明(Android 11+)

Android 11(API 30)引入了包可见性限制,需要在 AndroidManifest 中声明 <queries> 才能检测飞书是否安装。本插件已在 utssdk/app-android/AndroidManifest.xml 中内置了此配置:

<queries>
    <package android:name="com.ss.android.lark" />
    <package android:name="com.larksuite.suite" />
    <intent>
        <action android:name="android.intent.action.VIEW" />
        <data android:scheme="lark" android:host="ssoclient" />
    </intent>
</queries>

一般无需手动添加。


插件目录结构


cnd-feishu-auth/
├── package.json # 插件元信息
└── utssdk/
├── interface.uts # 跨平台类型定义
├── unierror.uts # 错误码常量
├── app-android/
│ ├── index.uts # Android 实现(含 FeishuCallbackActivity)
│ ├── config.json # Android 构建配置
│ ├── AndroidManifest.xml # Activity 注册 + queries 声明
│ └── libs/
│ └── larksso-3.0.10.aar # 飞书 Android SDK
└── app-ios/
├── index.uts # iOS 实现
├── config.json # iOS 构建配置(frameworks 依赖)
└── Frameworks/
├── LarkSSOSDK.framework # 飞书 iOS SDK
└── LarkSSO.bundle # SDK 资源包

隐私、权限声明

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

Android - 权限: android.permission.INTERNET 用途: 网络访问,用于飞书 SDK 通信 - 权限: android.permission.ACCESS_NETWORK_STATE 用途:检查网络连接状态,SDK 内部判断网络可用性 iOS: 无

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

插件自身不采集任何数据,插件使用的飞书移动端 SDK 采集数据请参考其官方说明:https://open.feishu.cn/document/common-capabilities/sso/mobile-app/sdk

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

许可协议

MIT协议

暂无用户评论。