飞书网页应用免登

飞书网页应用免登

背景

开放平台应用支持小程序、网页和机器人三种能力。小程序和网页可在应用中心打开。

应用可通过开放平台身份验证能力获取用户身份,完成用户在应用中的登录流程。身份验证时,客户端内免登浏览器上需要用户完成扫码登录或密码登录

需求:我们就是要实现,在飞书客户端打开网页免登。
如何实现网页应用在飞书客户端内的免登操作,在用户打开网页应用时,弹出授权登录页面,授权通过后直接完成登录操作?

客户端内网页免登(新)

直接参考官网:https://open.feishu.cn/document/client-docs/build-login-free-system-#6efde855
网页应用免登(SSO): https://open.feishu.cn/document/home/quickly-create-a-login-free-web-app/introduction

飞书5.1开始,客户端内网页免登建议采用新方案进行
新方案在优化了获取临时授权码的方式,采用 API 的方式获取授权码。其他流程未进行修改,请参考老免登流程。
开放平台会校验应用 当前访问URL 的合法性,请参考步骤三:免登流程(可选)。

免登步骤:
第一步: 网页前端调用tt.requestAccess获取临时授权码;
第二步: 网页后端调用获取 user_access_token获取 user_access_token
第三步: 网页后端调用获取用户信息 获取到用户身份,并设置应用自身登录态。

相比旧版免登方式,使用此方法的优点:

  • 不会阻塞网页内容渲染
  • 避免重定向失败导致无法访问网页
  • 无需进行复杂的 URL encode 处理

网页前端调用 tt.requestAccess 获取临时授权码(无需重定向参数)

示例代码

  1. 示例代码下载
    飞书开放平台提供了网页免登(SSO)的示例代码,帮助开发者快速实现网页应用的免登录功能。以下是下载和运行示例代码的步骤:
    执行以下命令下载示例代码:
curl https://sf3-cn.feishucdn.com/obj/open-platform-opendoc/89a72c38427997dd39899862783c740f_VHYlYYScyD.zip -o web_app_with_auth.zip
  1. 解压下载的文件:
unzip web_app_with_auth.zip
cd web_app_with_auth/python
  1. 修改 .env 文件中的应用凭证信息为实际的应用凭证数据:
    APP_ID=你的应用ID
    APP_SECRET=你的应用密钥

应用凭证信息可以在 开发者后台的 凭证与基础信息 页面查看。

  1. 创建并激活 Python 虚拟环境:
python3 -m venv venv
. venv/bin/activate
  1. 安装依赖:
pip install -r requirements.txt
  1. 启动服务:
python server.py

启动成功后会生成临时域名,可用于测试网页免登功能。

代码分析解释

前端代码
  1. 获取用户语言设置
let lang = window.navigator.language;
console.log(lang);

这两行代码获取了用户浏览器的语言设置,并将其存储在变量 lang 中,同时在控制台打印该语言信息。这一设置用于后续根据用户语言展示不同的文本内容。

  1. apiAuth函数
function apiAuth() {
   
    
    
    if (!window.h5sdk) {
   
    
    
        console.log('invalid h5sdk')
        alert('please open in feishu')
        return
    }
    // ...
}
  • 该函数用于进行API认证。首先检查 window.h5sdk 是否存在,如果不存在,则认为当前环境不是飞书环境,输出错误信息并弹出提示框,然后终止函数执行。
fetch(`/get_appid`).then(response1 => response1.json().then(res1 => {
   
    
    
    console.log("get appid succeed: ", res1.appid);
    // ...
})).catch(function (e) {
   
    
    
    console.error(e)
})
  • 通过 fetch 方法向服务端的 /get_appid 路由发送请求,获取应用的 app_id 。为了安全起见, app_id 不会在前端明文书写,而是从服务端获取。如果请求成功,将打印 app_id ;如果请求失败,将在控制台输出错误信息。
window.h5sdk.error(err => {
   
    
    
    throw('h5sdk error:', JSON.stringify