Last active
November 27, 2024 08:27
-
-
Save aiyogg/67a1330b68b0aadb6f43b9f8e8185a38 to your computer and use it in GitHub Desktop.
Wechat Work SSO
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name 一键 SSO 登录 | |
// @namespace http://tampermonkey.net/ | |
// @version 2024-10-14 | |
// @description 在企业微信中点击接收到 BOT 的链接后,自动完成扫码登录 | |
// @author Chuck | |
// @match https://sso.exmaple-company-internal.com/login.html?* | |
// @match https://sso.exmaple-company-external.com/login.html?* | |
// @icon https://www.google.com/s2/favicons?sz=64&domain=work.weixin.qq.com | |
// @grant GM_xmlhttpRequest | |
// ==/UserScript== | |
const target = | |
new URLSearchParams(window.location.search).get('target') ?? | |
btoa('YOUR_DEFAULT_TARGET_URL') | |
const service = new URLSearchParams(window.location.search).get('service') ?? 'YOUR_DEFAULT_SERVICE' | |
const APP_ID = 'APP_ID' | |
const AGENT_ID = 'AGENT_ID' | |
const REDIRECT_URI = 'YOUR_COMPANYS_REDIRECT_URI' | |
const STATE = btoa( | |
JSON.stringify({ | |
target: encodeURIComponent(target), | |
service, | |
cropId: APP_ID, | |
wechatAppId: AGENT_ID, | |
upstreamCropId: null, | |
upstreamWechatAppId: null, | |
}) | |
) | |
const WECHAT_WORK_KEY = 'YOUR_WECHAT_BOT_KEY' | |
function request(url, method = 'GET', data = null) { | |
return new Promise((resolve, reject) => { | |
GM_xmlhttpRequest({ | |
url, | |
method, | |
data, | |
headers: { | |
'Content-Type': 'application/json', | |
}, | |
onload: (response) => resolve(response.responseText), | |
onerror: (error) => reject(error), | |
}) | |
}) | |
} | |
const redirectUri = `${REDIRECT_URI}?state=${STATE}` | |
;(async function () { | |
'use strict' | |
const response = await request( | |
`https://open.work.weixin.qq.com/wwopen/sso/qrConnect?login_type=jssdk&appid=${APP_ID}&agentid=${AGENT_ID}&redirect_uri=${redirectUri}&lang=zh&version=1.2.4` | |
) | |
try { | |
const settings = response.match(/window\.settings\s*=\s*(\{.*?\});/)[1] | |
const { key } = JSON.parse(settings) | |
console.log('key', key) | |
await request( | |
`https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=${WECHAT_WORK_KEY}`, | |
'POST', | |
JSON.stringify({ | |
msgtype: 'template_card', | |
template_card: { | |
card_type: 'text_notice', | |
main_title: { | |
title: 'SSO登录确认', | |
desc: '点击跳转登录确认', | |
}, | |
card_action: { | |
type: 1, | |
url: `https://open.work.weixin.qq.com/wwopen/sso/confirm2?k=${key}`, | |
title: '跳转登录确认', | |
}, | |
}, | |
}) | |
) | |
// 轮询 | |
while (true) { | |
await new Promise((resolve) => setTimeout(resolve, 1000)) | |
const res = await request( | |
`https://open.work.weixin.qq.com/wwopen/sso/l/qrConnect?callback=jsonpCallback&key=${key}&redirect_uri=${encodeURIComponent( | |
redirectUri | |
)}&appid=${APP_ID}&lastStatus=QRCODE_SCAN_ING&_${Date.now()}` | |
) | |
console.log(res) | |
const data = res.match(/jsonpCallback\((.*)\)/)[1] | |
const { status, auth_code } = JSON.parse(data) | |
if (status === 'QRCODE_SCAN_NEVER') { | |
console.log('扫码中') | |
} else if (status === 'QRCODE_SCAN_ERR') { | |
console.log('扫码失败') | |
if (window.confirm('二维码已过期,重新接收?')) { | |
window.location.reload() | |
} | |
} else if (status === 'QRCODE_SCAN_ING') { | |
console.log('等待确认登录') | |
} else if (status === 'QRCODE_SCAN_SUCC') { | |
console.log('登录成功') | |
console.log('auth_code', auth_code) | |
window.location.href = `${redirectUri}&code=${auth_code}` | |
break | |
} | |
} | |
} catch (e) { | |
console.log(e) | |
} | |
})() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment