2006世界杯巴西
微信授权全链路打通指南
近期,我在致力于打造自己的小程序产品时,迎来了一项关键性的进展——微信相关授权流程 的完整实现。从用户登录到权限获取,我们细致入微地梳理并实现了每一项授权机制,确保了用户体验的流畅与安全。
后端代码采用的是Nest 提供的伪代码,整体思路已提供。
微信小程序授权
授权流程:
用户在小程序中点击登录按钮,触发
wx.login()
获取
code
。
小程序将
code
发送到后端服务器。
后端通过微信接口
jscode2session
使用
code
获取
session\_key
和
openid
。
后端返回
session\_key
和
openid
给前端。
前端获取
session\_key
和
openid
,使用
wx.getUserProfile()
获取用户信息(如昵称、头像等)。
如果需要,可以将用户信息(如昵称、头像等)发送到后端进行存储或处理。
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 伪代码实现
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认证方式,使第三方网站或应用能够获取用户基本信息,实现用户身份识别。
授权流程
发起授权
用户点击登录/授权按钮
生成授权链接
跳转至微信授权页面
用户确认
用户选择是否授权
确认后获取临时授权码
code
换取 Access Token
服务端使用
code
换取
access\_token
获取用户的
openid
和
access\_token
获取用户信息
使用
access\_token
和
openid
调用微信接口获取用户详细信息
系统内部处理
创建或更新用户信息
生成系统内部登录态
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('获取用户信息失败');
}
}
}
微信开放平台授权
特点:
适用于第三方应用
支持移动应用、网站应用等
需要开发者资质认证
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 失败');
}
}
}
企业微信授权
企业微信授权是针对企业内部应用和员工的身份认证机制,提供更严格和精细的权限控制。
特点:
主要面向企业内部应用
更强的权限控制
安全性更高
授权流程
发起授权
员工访问企业内部应用
触发登录机制(扫码/输入)
生成企业微信授权链接
身份验证
跳转企业微信登录页
员工确认身份
获取临时授权码
换取用户信息
服务端使用
code
换取用户标识
获取
userid
调用接口获取用户详细信息
系统内部处理
验证员工身份
检查权限状态
生成系统内部登录态
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应用
|
|
小程序授权
|
是
|
免费
|
小程序登录、开放平台
|
|
公众号授权
|
部分可用
|
免费+增值服务
|
公众号相关应用(服务号、订阅号)
|
|
企业微信
|
否
|
有费用
|
企业内部协作
|