網頁 H5 微應用接入釘釘自動登錄

??關于云審批
云審批(cloud approve) ,一款專為小微企業打造,支持多租戶的在線審批神器。它簡化了申請和審批流程,讓您隨時隨地通過手機或電腦完成請款操作。員工一鍵提交申請,審批者即時響應,方便快捷。同時,云審批提供全面的數據記錄與分析,助力企業實現財務管理透明化、智能化,安全高效,讓企業的信息數字化管理變得簡單輕松!最后,重要的事情說三遍📢:開源、開源、所有代碼開源。
👉GITHUB開源地址 👈
👉飛書在線文檔👈

概述

釘釘免登(此處專指自建H5微應用,官方文檔)是一種便捷的登錄機制,當用戶已在釘釘客戶端(包括PC端和移動端)完成登錄后,通過工作臺訪問我們的網站時,系統能夠自動識別并完成用戶身份驗證,無需重復輸入登錄信息。該功能廣泛應用于微信、飛書、抖音等主流平臺,為用戶提供無縫的跨平臺使用體驗。

流程詳解

數據表

登錄模塊設計到兩個表:賬號表/Account、員工表/Staff。

賬號/Account

此表為登錄到平臺的賬戶信息,支持傳統的賬密方式、釘釘免登等方式,并記錄與之關聯的員工ID

字段名中文名類型必填默認值說明
id編號Int唯一標識
cid企業IDInt關聯企業
name賬號名稱String
pwd密碼String加密
type類型String登錄類型
sid員工IDInt關聯員工
active是否生效Booleanfalse
addOn錄入日期Int

登錄類型:

  • dingding=釘釘
  • wechat=微信
  • phone=手機號(未來支持手機驗證碼登錄)
  • other=其它(傳統密碼登錄)

員工/Staff

字段名中文名類型必填默認值說明
id編號Int唯一標識
cid企業IDInt關聯企業
name員工名稱String
phone電話號碼String
summary描述String

免登流程

  • 準備階段
    • 企業管理員登錄釘釘開發者后臺,創建應用并配置網頁功能
    • 獲取應用的AppKeyAppSecrect
  • 邏輯實現
    • 新建釘釘登錄專用頁面(dingding.html)
    • 在頁面中獲取兩個參數cid(企業ID)corpId(釘釘內企業ID)
    • 前端調用釘釘接口獲取授權碼/CODE
    • 后端拿到上述 CODE 后通過AppKeyAppSecrect獲取到用戶信息(包含唯一編號 unionid、姓名 name 等)
    • 構建唯一賬戶名:D_{unionid}_{name}
    • 檢查強求賬戶名是否存在于 Account 表
    • 如存在則判斷是否生效,若生效返回token,否則報錯
    • 若不存在
      • 自動創建賬戶信息
      • 檢索企業下同名員工,若不存在則自動創建并關聯到賬戶對象
      • 若配置了賬戶自動生效,返回 token,否則前端提示賬戶未激活請聯系管理員
  • 部署上線
    • 部署平臺獲取到登錄頁 URL(https://{域名}/dingding.html)
    • 在釘釘后臺填入上述地址后發布應用版本
    • 用戶在釘釘客戶端工作臺添加應用后即可訪問

新建 dingding.html

我們在前端項目代碼下新建對應頁面:

并在 rsbuild.config.mjs中配置多頁面:

export default defineConfig({source:{entry:{index: './src/index.js',dingding: './src/pages/dingding/index.js'}}
})

至此,我們可以通過 http://{IP}/dingding.html訪問到該頁面,作為釘釘免登的入口😄。

編寫登錄頁面邏輯

登錄頁主要組件 App.vue 代碼如下:

<template><div style="width: 80%; margin: 40px auto;"><div class="text-center" v-if="!errMsg"><n-spin :show="working"><template #description>釘釘客戶端登錄中,請稍候...</template></n-spin></div><n-alert v-else :type show-icon title="釘釘自動登錄失敗" :bordered="false">{{ errMsg }}</n-alert></div>
</template><script setup>import { NSpin, NAlert, useMessage, NMessageProvider } from 'naive-ui'import { requestAuth } from "./dingding"import { checkLocalToken, saveLocalToken } from "../login"const msg = useMessage()let cid = undefinedlet corpId = undefinedconst debug = import.meta.env.DEV;let working = ref(true)let errMsg = ref("")let type = ref("info")const onMsg = (msg, isError=true)=>{errMsg.value = msgtype.value = isError?"error":"info"}const tryToAutoLogin = ()=>{requestAuth(corpId).then(code=>{msg.info(`CODE=${code}`)fetch("/common/login-with-dingding",{method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify({ cid, code })}).then(response => response.json()).then(({ success, data, message }) => {if(success==true){msg.success(`登陸成功`)saveLocalToken(data)gotoIndex()}else{const messages = {E01 : "您的釘釘賬戶為首次登錄,請先聯系管理員完成激活",E02 : "您的釘釘賬戶關聯未激活,請聯系企業管理員",E03 : "找不到當前釘釘賬戶關聯的員工"}onMsg(messages[message]||message, !messages[message])}})}).catch(e=>onMsg(typeof(e)=='string'?e:e.message))}const gotoIndex = ()=> location.href = "/"onMounted(() => {let u = new URL(location.href)cid = u.searchParams.get('cid')corpId = u.searchParams.get('corpId')if(checkLocalToken())return gotoIndex()tryToAutoLogin()})
</script>
// dingding.js
import { runtime } from 'dingtalk-jsapi'export const requestAuth = async (corpId)=> {let { code } = await runtime.permission.requestAuthCode({corpId})return code
}//login.js
const NAME = import.meta.env.PUBLIC_HEADER_TOKEN
const CREATED = `${NAME}_CREATED`/*** 檢查本地 token 是否在有效期內* @param {Number} expired - token 有效期,默認12小時,單位毫秒* @returns {Boolean} true 時為 token 有效*/
export const checkLocalToken = (expired=12*60*60*1000)=>{let token = localStorage.getItem(NAME)if(!token)  return falselet expire = localStorage.getItem(CREATED)||0if(Date.now() - expire>=expired)return falsereturn true
}export const saveLocalToken = token=>{localStorage.setItem(NAME, token)localStorage.setItem(CREATED, Date.now())
}

這里不得不吐槽下釘釘開發平臺的官網文檔,新舊版 API 文檔特別容易讓人混亂,引入dingtalk-jsapi的話需要查看舊版文檔😔。

編寫后端與釘釘服務器的交互

const { get, post } = require('axios')
const { loadWithCidAndName } = require("./ConstantService")
const logger = require('../common/logger')/*** @typedef {Object} DDTokenResponse - 釘釘獲取token效應值* @property {String} access_token - token值* @property {Number} expires_in - 有效期(單位秒)* @property {Number} errcode - 錯誤代碼* @property {String} errmsg - 錯誤信息** @typedef {Object} DDUser - 釘釘用戶信息* @property {String} userid* @property {String} unionid - 唯一編號* @property {String} name - 用戶名稱** @typedef {Object} DDUserResponse - 釘釘用戶信息響應值* @property {DDUser} result* @property {String} request_id* @property {Number} errcode - 錯誤代碼* @property {String} errmsg - 錯誤信息*/const DING_HOST = "https://oapi.dingtalk.com"let localToken = {value: "",expire: 0
}const isTokenExpired = ()=> !localToken.value || localToken.expire<=Date.now()
const log = (msg, level='info')=> logger[level](`[釘釘] ${msg}`)exports.loginWithCode = async (cid, code)=>{if(isTokenExpired()){/**@type {CompanyConfig} */let cfg = await loadWithCidAndName(cid)if(!cfg || !(cfg.ddAppKey && cfg.ddAppSecret))throw `企業未配置釘釘登錄`let url = `${DING_HOST}/gettoken?appkey=${cfg.ddAppKey}&appsecret=${cfg.ddAppSecret}`/**@type {{data:DDTokenResponse}} */let { data } = await get(url)if(data.errcode != 0){log(`獲取企業 token 失敗:${data.errcode}|${data.errmsg}`, 'error')throw data.errmsg}localToken.value = data.access_tokenlocalToken.expire = Date.now() + data.expires_in*1000log(`更新 TOKEN 為 ${localToken.value}(EXPIRED=${data.expires_in}`)}let url = `${DING_HOST}/topapi/v2/user/getuserinfo?access_token=${localToken.value}`/**@type {{data:DDUserResponse}} */let { data } = await post(url, { code })if(data.errcode != 0){log(`[釘釘] 獲取用戶信息失敗:${data.errcode}|${data.errmsg}`, 'error')throw data.errmsg}global.isDebug && log(`獲取用戶信息 ${data.result.userid}/${data.result.name}`, 'debug')return data.result
}

部署及上線

創建釘釘H5微應用

  1. 登錄釘釘開發者后臺。
  2. 單擊應用開發 > 企業內部應用 > 釘釘應用 > 創建應用
  3. 填寫應用信息。
配置項是否必填配置說明
應用名稱輸入應用名稱,應用名稱最小長度為 2 個字符。
應用描述簡要描述應用提供的產品或服務,應用描述最小長度為 4 個字符。
應用圖標上傳應用圖標,圖標要求 JPG/PNG 格式、240 px * 240 px 以上、1:1 、2 MB 以內的無圓角圖標。
  1. 單擊保存,進入應用詳情頁。
  2. 如果你需要開發 AI 應用、小程序、網頁應用、酷應用和機器人功能,你需要添加應用能力。

發布應用

創建應用后,需要發布才能看到噢


接著在釘釘客戶端就能看到此應用啦🎉

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/81987.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/81987.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/81987.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

idea無法識別Maven項目

把.mvn相關都刪除了 導致Idea無法識別maven項目 或者 添加導入各個模塊 最后把父模塊也要導入

飛槳paddle import fluid報錯【已解決】

跟著飛槳的安裝指南安裝了paddle之后 pip install paddlepaddle有一個驗證&#xff1a; import paddle.fluid as fluid fluid.install check.run check()報錯情況如下&#xff0c;但是我在pip list中&#xff0c;確實看到了paddle安裝上了 我import paddle別的包&#xff0c…

現代化SQLite的構建之旅——解析開源項目Limbo

現代化SQLite的構建之旅——解析開源項目Limbo 在當今飛速發展的技術世界中,輕量級且功能強大的數據庫已成為開發者的得力助手。當我們談論輕量級數據庫時,SQLite無疑是一個舉足輕重的名字。然而,隨著技術的進步,我們對數據庫的需求也變得更加多樣化。這正是Limbo項目誕生…

MinIO:從入門到精通,解鎖云原生存儲的奧秘

一、引言&#xff1a;為什么 MinIO 正在重塑存儲世界&#xff1f; 在云計算和大數據時代&#xff0c;傳統存儲系統面臨擴展性差、成本高、兼容性不足等挑戰。MinIO 憑借其 S3 兼容性、分布式架構、高性能存儲 等特性&#xff0c;成為企業構建現代化存儲基礎設施的首選。 本文…

vscode怎么關閉自動定位文件

關閉自動定位文件功能 方式1 在設置中搜索: explorer.autoReveal 方式2 直接在settings.json中增加"explorer.autoReveal": false 添加類似jetbrains IDE的文件定位功能 可以直接安裝插件市場搜索niushuaibing.vs-location, 安裝后會有文件定位按鈕, 點擊后即可…

學習路之uniapp--unipush2.0推送功能--給自己發通知

學習路之uniapp--unipush2.0推送功能--給自己發通知 一、綁定云空間及創建云函數二、編寫發送界面三、效果后期展望&#xff1a; 一、綁定云空間及創建云函數 package.json {"name": "server-push","dependencies": {},"main": "…

什么是VR展示?VR展示的用途

隨著科技的迅猛發展&#xff0c;我們步入一個全新的數字時代。在這個時代&#xff0c;虛擬現實&#xff08;VR&#xff09;技術嶄露頭角&#xff0c;逐步改變我們對世界的認知。全景展示廳作為VR技術與傳統展覽藝術的完美結合&#xff0c;以獨特的全景視角&#xff0c;引領我們…

抖音IP屬地跟無線網有關嗎?如何更改

IP屬地顯示功能讓許多用戶感到好奇——為什么自己的位置信息有時準確&#xff0c;有時卻顯示在其他城市&#xff1f;這時&#xff0c;用戶會疑惑&#xff1a;抖音IP屬地跟無線網有關系嗎&#xff1f;抖音的IP屬地顯示與其所使用的網絡類型&#xff08;包括無線網&#xff09;密…

JESD204 ip核使用與例程分析(二)

JESD204 ip核使用與例程分析(二) JESD204時鐘方案專用差分時鐘對例程分析jesd204_0_transport_layer_demapperjesd204_0_sig_chkjesd204_0_clockingjesd204_0 ip核port寄存器AXI-LITE寄存器配置jesd204_phy ip核JESD204時鐘方案 圖3-1所示為最通用、靈活的時鐘解決方案。在圖…

微軟全新開源的Agentic Web網絡項目:NLWeb,到底是什么 ?

目錄 1、背景 2、NLWeb是什么&#xff1f; 3、NLWeb是如何工作的&#xff1f; 3.1 技術原理 3.2 對發布者的價值 3.3 核心團隊與合作伙伴 4、快速入門指南 5、延伸閱讀 Agentic&#xff1a;Agent的形容詞&#xff0c;Agentic指系統由大型語言模型&#xff08;LLM&#…

前端性能優化的秘密武器:Preload 與 Prefetch 的深度解析

前端性能優化的秘密武器&#xff1a;Preload 與 Prefetch 的深度解析 在前端開發中&#xff0c;頁面加載速度直接影響用戶體驗和業務轉化率。而“資源預加載”技術&#xff0c;正是優化加載性能的核心手段之一。本文將深入淺出地講解 Preload 與 Prefetch 這兩項技術&#xff…

App Builder技術選型指南:從AI編程到小程序容器,外賣App開發實戰

在2025年快速迭代的技術生態中&#xff0c;開發者構建App的路徑愈發多樣化。本文以開發一個同城外賣App為例&#xff0c;對比當前主流的AI編程工具&#xff08;如Cursor、GitHub Copilot、Trae&#xff09;與小程序容器技術&#xff08;如FinClip&#xff09;的優劣勢、難易度及…

深度學習入門到實戰:用PyTorch打通數學、張量與模型訓練全鏈路?

本文較長&#xff0c;建議點贊收藏&#xff0c;以免遺失。更多AI大模型應用開發學習視頻及資料&#xff0c;盡在聚客AI學院。 一. 人工智能、機器學習與深度學習的關系 1.1 概念層次解析 人工智能&#xff08;AI&#xff09;&#xff1a;使機器模擬人類智能的廣義領域 機器學…

windows服務器部署jenkins工具(一)

jenkins作為一款常用的構建發布工具&#xff0c;極大的簡化了項目部署發布流程。jenkins通常是部署在linux服務上&#xff0c;今天給大家分享的是windows服務器上如何搭建jenkins發布工具。 1.首先第一步還是看windows安裝docker 這篇文章哈&#xff0c;當然也可以不采用docke…

前端開發規范性利器系列之:ESLint

前言 我是一名從事低代碼平臺研發的前端CV程序猿&#xff0c;有幾十名像我一樣的小伙伴協同研發。在長期的多人協作和滾動迭代中&#xff0c;不出意外&#xff0c;代碼中會充斥各種“壞味道”&#xff0c;如代碼風格不統一、擴展性和靈活性降低等問題。我們是如何解決這些問題的…

數據結構知識點匯總

1、在數據結構中&#xff0c;隨機訪問是指能夠直接訪問任一元素&#xff0c;而不需要從特定的起始位置開始&#xff0c;也不需要按順序訪問其他元素。這種訪問方式通常不涉及遍歷。例如&#xff0c;數組&#xff08;array&#xff09;支持隨機訪問&#xff0c;你可以直接通過索…

ubuntu中上傳項目至GitHub倉庫教程

一、到github官網注冊用戶 1.注冊用戶 地址&#xff1a;https://github.com/ 2.安裝Git 打開終端&#xff0c;輸入指令git,檢查是否已安裝Git 如果沒有安裝就輸入指令 sudo apt-get install git 二、上傳項目到github 1.創建項目倉庫 進入github主頁&#xff0c;點擊號…

C#在 .NET 9.0 中啟用二進制序列化:配置、風險與替代方案

在 .NET 9.0 中啟用二進制序列化&#xff1a;配置、風險與替代方案 引言一、啟用二進制序列化的步驟二、實現序列化與反序列化三、安全風險與緩解措施四、推薦替代方案五、總結 引言 在 .NET 生態中&#xff0c;二進制序列化&#xff08;Binary Serialization&#xff09;曾是…

如何解決鴻蒙應用閃退問題

如何解決鴻蒙應用閃退問題 本文是一份面向 ArkTS&#xff0f;JavaScript&#xff0f;C 多語言開發者的綜合性排查與優化手冊&#xff0c;覆蓋 HarmonyOS/OpenHarmony 5.x 時代 常見閃退根因、診斷流程、調試技巧、CI 監控及線上防護方案&#xff0c;力爭幫你把 Crash 數量降到 …

【Java高階面經:微服務篇】4.大促生存法則:微服務降級實戰與高可用架構設計

一、降級決策的核心邏輯:資源博弈下的生存選擇 1.1 大促場景的資源極限挑戰 在電商大促等極端流量場景下,系統面臨的資源瓶頸呈現指數級增長: 流量特征: 峰值QPS可達日常的50倍以上(如某電商大促下單QPS從1萬突增至50萬)流量毛刺持續時間短(通常2-4小時),但對系統穩…