企业微信&小程序授权全链路打通指南

企业微信&小程序授权全链路打通指南

近期,我在致力于打造自己的小程序产品时,迎来了一项关键性的进展——微信相关授权流程的完整实现。从用户登录到权限获取,我们细致入微地梳理并实现了每一项授权机制,确保了用户体验的流畅与安全。

微信小程序授权image授权流程:用户在小程序中点击登录按钮,触发 wx.login() 获取 code。小程序将 code 发送到后端服务器。后端通过微信接口 jscode2session 使用 code 获取 session_key 和 openid。后端返回 session_key 和 openid 给前端。前端获取 session_key 和 openid,使用 wx.getUserProfile() 获取用户信息(如昵称、头像等)。如果需要,可以将用户信息(如昵称、头像等)发送到后端进行存储或处理。代码语言:plain复制wx.login({

success: function(res) {

if (res.code) {

// 将 code 发送到服务器

wx.request({

url: 'https://localhost:8080/api/login',

method: 'POST',

data: {

code: res.code

},

success: function(response) {

// 处理服务器返回的数据

console.log(response.data);

}

});

}

}

});下面是Nest 伪代码实现

代码语言:javascript代码运行次数:0运行复制import { Injectable } from '@nestjs/common';

import { HttpService } from '@nestjs/axios';

import { firstValueFrom } from 'rxjs';

interface MiniProgramLoginResponse {

openid: string;

session_key: string;

unionid?: string;

errcode?: number;

errmsg?: string;

}

@Injectable()

export class MiniProgramAuthService {

constructor(private readonly httpService: HttpService) {}

async login(code: string): Promise {

const url = 'https://api.weixin.qq.com/sns/jscode2session';

try {

const response = await firstValueFrom(

this.httpService.get(url, {

params: {

appid: process.env.MINIPROGRAM_APPID,

secret: process.env.MINIPROGRAM_APPSECRET,

js_code: code,

grant_type: 'authorization_code'

}

})

);

return response.data;

} catch (error) {

throw new Error('小程序登录失败');

}

}

// 解密用户敏感信息

async decryptUserInfo(sessionKey: string, encryptedData: string, iv: string) {

// 实现微信小程序用户信息解密逻辑

// 通常需要使用第三方加密库如 crypto-js

}

}微信网页授权(OAuth 2.0)网页授权是通过微信官方提供的OAuth2.0认证方式,使第三方网站或应用能够获取用户基本信息,实现用户身份识别。

imageimage授权流程发起授权用户点击登录/授权按钮生成授权链接跳转至微信授权页面用户确认用户选择是否授权确认后获取临时授权码 code换取 Access Token服务端使用 code 换取 access_token获取用户的 openid 和 access_token获取用户信息使用 access_token 和 openid调用微信接口获取用户详细信息系统内部处理创建或更新用户信息生成系统内部登录态代码语言:javascript代码运行次数:0运行复制import { Injectable } from '@nestjs/common';

import { HttpService } from '@nestjs/axios';

import { firstValueFrom } from 'rxjs';

// 用户授权信息接口定义

interface WechatUserInfo {

openid: string; // 用户唯一标识

nickname: string; // 用户昵称

sex: number; // 用户性别

province: string; // 省份

city: string; // 城市

country: string; // 国家

headimgurl: string; // 头像地址

privilege: string[]; // 用户特权信息

unionid?: string; // 开放平台唯一标识

}

@Injectable()

export class WebAuthService {

constructor(private readonly httpService: HttpService) {}

// 生成授权链接

generateAuthUrl(redirectUri: string, scope: 'snsapi_base' | 'snsapi_userinfo' = 'snsapi_userinfo') {

const baseUrl = 'https://open.weixin.qq.com/connect/oauth2/authorize';

const params = new URLSearchParams({

appid: process.env.WECHAT_APPID,

redirect_uri: redirectUri,

response_type: 'code',

scope: scope,

state: 'STATE#wechat_redirect' // 自定义参数,用于回传

});

return `${baseUrl}?${params}#wechat_redirect`;

}

// 获取 Access Token

async getAccessToken(code: string) {

const url = 'https://api.weixin.qq.com/sns/oauth2/access_token';

try {

const response = await firstValueFrom(

this.httpService.get(url, {

params: {

appid: process.env.WECHAT_APPID,

secret: process.env.WECHAT_APPSECRET,

code: code,

grant_type: 'authorization_code'

}

})

);

return response.data;

} catch (error) {

throw new Error('获取 Access Token 失败');

}

}

// 获取用户信息

async getUserInfo(accessToken: string, openid: string): Promise {

const url = 'https://api.weixin.qq.com/sns/userinfo';

try {

const response = await firstValueFrom(

this.httpService.get(url, {

params: {

access_token: accessToken,

openid: openid,

lang: 'zh_CN'

}

})

);

return response.data;

} catch (error) {

throw new Error('获取用户信息失败');

}

}

}微信开放平台授权image特点:适用于第三方应用支持移动应用、网站应用等需要开发者资质认证代码语言:javascript代码运行次数:0运行复制import { Injectable } from '@nestjs/common';

import { HttpService } from '@nestjs/axios';

import { firstValueFrom } from 'rxjs';

// 定义开放平台授权响应接口

interface OpenPlatformAuthResponse {

access_token: string; // 接口调用凭证

expires_in: number; // access_token 过期时间

refresh_token: string; // 刷新 token

openid: string; // 授权用户唯一标识

scope: string; // 用户授权的作用域

unionid: string; // 开放平台唯一标识

}

@Injectable()

export class OpenPlatformAuthService {

constructor(private readonly httpService: HttpService) {}

/**

* 获取 access_token

* @param code 授权码

* @returns 授权响应信息

*/

async getAccessToken(code: string): Promise {

// 微信获取 access_token 的接口地址

const url = 'https://api.weixin.qq.com/sns/oauth2/access_token';

try {

// 使用授权码换取 access_token

const response = await firstValueFrom(

this.httpService.get(url, {

params: {

// 从环境变量读取开放平台 AppID

appid: process.env.OPEN_PLATFORM_APPID,

// 从环境变量读取开放平台密钥

secret: process.env.OPEN_PLATFORM_APPSECRET,

// 授权码

code: code,

// 授权类型,固定值

grant_type: 'authorization_code'

}

})

);

return response.data;

} catch (error) {

// 捕获并抛出授权失败的错误

throw new Error('开放平台授权失败');

}

}

/**

* 刷新 access_token

* @param refreshToken 刷新 token

* @returns 新的授权信息

*/

async refreshAccessToken(refreshToken: string) {

// 微信刷新 access_token 的接口地址

const url = 'https://api.weixin.qq.com/sns/oauth2/refresh_token';

try {

// 使用 refresh_token 换取新的 access_token

const response = await firstValueFrom(

this.httpService.get(url, {

params: {

// 开放平台 AppID

appid: process.env.OPEN_PLATFORM_APPID,

// 授权类型,固定值

grant_type: 'refresh_token',

// 用于刷新的 token

refresh_token: refreshToken

}

})

);

return response.data;

} catch (error) {

// 捕获并抛出刷新 Token 失败的错误

throw new Error('刷新 Token 失败');

}

}

}企业微信授权企业微信授权是针对企业内部应用和员工的身份认证机制,提供更严格和精细的权限控制。

image特点:主要面向企业内部应用更强的权限控制安全性更高授权流程发起授权员工访问企业内部应用触发登录机制(扫码/输入)生成企业微信授权链接身份验证跳转企业微信登录页员工确认身份获取临时授权码换取用户信息服务端使用 code 换取用户标识获取 userid调用接口获取用户详细信息系统内部处理验证员工身份检查权限状态生成系统内部登录态代码语言:javascript代码运行次数:0运行复制import { Injectable } from '@nestjs/common';

import { HttpService } from '@nestjs/axios';

import { firstValueFrom } from 'rxjs';

// 定义企业微信授权响应接口

interface EnterpriseWechatAuthResponse {

access_token: string; // 企业接口调用凭证

expires_in: number; // access_token 过期时间

user_ticket?: string; // 用户票据(可选)

user_info?: {

userid: string; // 企业成员 ID

name: string; // 成员名称

department: number[]; // 部门 ID 列表

};

}

@Injectable()

export class EnterpriseWechatAuthService {

constructor(private readonly httpService: HttpService) {}

/**

* 获取企业微信用户信息

* @param code 临时授权码

* @returns 用户信息和 access_token

*/

async getUserInfo(code: string): Promise {

// 获取企业 access_token 的接口地址

const tokenUrl = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken';

// 获取用户信息的接口地址

const userInfoUrl = 'https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo';

// 第一步:获取企业 access_token

// 需要使用企业 ID 和应用的秘钥

const tokenResponse = await firstValueFrom(

this.httpService.get(tokenUrl, {

params: {

// 从环境变量读取企业 ID

corpid: process.env.ENTERPRISE_CORPID,

// 从环境变量读取企业应用秘钥

corpsecret: process.env.ENTERPRISE_CORPSECRET

}

})

);

// 从响应中提取 access_token

const accessToken = tokenResponse.data.access_token;

// 第二步:使用 access_token 和临时授权码获取用户信息

const userInfoResponse = await firstValueFrom(

this.httpService.get(userInfoUrl, {

params: {

// 企业 access_token

access_token: accessToken,

// 临时授权码

code: code

}

})

);

return userInfoResponse.data;

}

}各个平台授权小结授权类型

个人是否可用

是否收费

主要适用场景

网页授权

免费

网站、H5应用

小程序授权

免费

小程序登录、开放平台

公众号授权

部分可用

免费+增值服务

公众号相关应用(服务号、订阅号)

企业微信

有费用

企业内部协作

2bb847a3dd3b21d084a2f2e6764e0e86.png)