企业微信推送卡片与单点登录实例演示

前言

企业内部系统常见的场景:
公司的内部系统通过企业微信给用户推送卡片通知,同时点击卡片通知可以单点登录到我们自己的系统,完成对应的操作

企业微信通知

我今天会来做一个简单的示例,实现:

企业微信卡片消息通知 + 单点登录跳转(SSO)

以下是一个完整的可运行示例,包括:

  1. 推送卡片消息(企业微信 API)
  2. 单点登录逻辑(生成一次性登录 token)
  3. 用户点击卡片后自动登录进入系统

🧩 一、系统架构说明

┌──────────────────────────────┐
│      内部业务系统(Backend) │
│                              │
│ ① 业务事件触发               │
│ ② 调用企业微信推送卡片 API   │
│ ③ 生成一次性登录 token        │
│ ④ 用户点击卡片 → 跳转链接    │
│ ⑤ 验证 token → 登录成功       │
└──────────────────────────────┘
          ↓
┌──────────────────────────────┐
│ 企业微信客户端               │
│  用户点击卡片                │
│  浏览器打开目标系统 URL      │
└──────────────────────────────┘

系统架构说明

🧠 二、技术栈建议

模块技术
后端接口Node.js + Express
企业微信消息推送企业微信官方 API
Token 管理JWT(或自定义一次性签名)
登录系统自有系统 API
部署内网服务器或云函数均可

🧾 三、卡片推送 + 登录实现示例

1️⃣ 企业微信卡片消息推送

使用企业微信官方接口:

// sendCardMessage.js
import fetch from "node-fetch";

const CORP_ID = "wwxxxxxx";
const CORP_SECRET = "your_secret";
const AGENT_ID = "1000002";

async function getAccessToken() {
  const resp = await fetch(
    `https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=${CORP_ID}&corpsecret=${CORP_SECRET}`
  );
  const data = await resp.json();
  return data.access_token;
}

export async function sendCardMessage(userId, title, description, ssoUrl) {
  const token = await getAccessToken();
  const body = {
    touser: userId,
    msgtype: "textcard",
    agentid: AGENT_ID,
    textcard: {
      title: title,
      description: description,
      url: ssoUrl, // 单点登录跳转地址
      btntxt: "立即处理",
    },
  };

  const resp = await fetch(
    `https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=${token}`,
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(body),
    }
  );

  return resp.json();
}

2️⃣ 生成单点登录链接(一次性 Token)

// tokenGenerator.js
import jwt from "jsonwebtoken";

const SECRET = "Your_Secret_Key";

export function generateSSOToken(userId) {
  return jwt.sign({ userId, ts: Date.now() }, SECRET, { expiresIn: "2m" }); // 2分钟有效
}

export function verifySSOToken(token) {
  try {
    return jwt.verify(token, SECRET);
  } catch (err) {
    return null;
  }
}

3️⃣ Express 后端逻辑(卡片点击登录)

// server.js
import express from "express";
import { sendCardMessage } from "./sendCardMessage.js";
import { generateSSOToken, verifySSOToken } from "./tokenGenerator.js";

const app = express();

// 模拟推送通知
app.get("/notify", async (req, res) => {
  const userId = "zhangsan";
  const token = generateSSOToken(userId);
  const ssoUrl = `https://your-domain.com/sso-login?token=${token}`;

  const resp = await sendCardMessage(
    userId,
    "审批待处理",
    "<div>您有一条待审批事项,请及时处理。</div>",
    ssoUrl
  );

  res.json(resp);
});

// 用户点击卡片后跳转登录
app.get("/sso-login", (req, res) => {
  const token = req.query.token;
  const data = verifySSOToken(token);

  if (!data) return res.status(401).send("登录链接已失效或无效。");

  // 模拟写入会话
  res.cookie("user", data.userId, { httpOnly: true });
  res.redirect("/dashboard");
});

// 模拟登录后页面
app.get("/dashboard", (req, res) => {
  res.send(`<h2>欢迎 ${req.cookies?.user || "访客"} 登录系统!</h2>`);
});

app.listen(3000, () => console.log("✅ Server started on http://localhost:3000"));

📱 四、流程示意

1️⃣ 内部系统触发事件(例如审批待处理)
2️⃣ 调用 /notify → 向指定员工推送卡片消息
3️⃣ 员工在企业微信中点击“立即处理”按钮
4️⃣ 跳转到 https://your-domain.com/sso-login?token=xxx
5️⃣ 系统验证 token → 自动登录 → 进入操作界面


🔐 五、安全建议

  • Token 必须设置 短期有效期(< 5分钟)
  • 每个 Token 一次性使用(存 Redis 以防重放)
  • 建议使用 HTTPS
  • 内网系统与企业微信服务器间调用应有 IP 白名单
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT小哥哥呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值