近期,我在致力于打造自己的小程序产品时,迎来了一项关键性的进展——微信相关授权流程的完整实现。从用户登录到权限获取,我们细致入微地梳理并实现了每一项授权机制,确保了用户体验的流畅与安全。
微信小程序授权
授权流程:
- 用户在小程序中点击登录按钮,触发
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<MiniProgramLoginResponse> {
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) {
}
}
微信网页授权(OAuth 2.0)
网页授权是通过微信官方提供的OAuth2.0认证方式,使第三方网站或应用能够获取用户基本信息,实现用户身份识别。
授权流程
- 发起授权
- 用户点击登录/授权按钮
- 生成授权链接
- 跳转至微信授权页面
- 用户确认
- 换取 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`;
}
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<WechatUserInfo> {
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;
refresh_token: string;
openid: string;
scope: string;
unionid: string;
}
@Injectable()
export class OpenPlatformAuthService {
constructor(private readonly httpService: HttpService) {}
async getAccessToken(code: string): Promise<OpenPlatformAuthResponse> {
const url = 'https://api.weixin.qq.com/sns/oauth2/access_token';
try {
const response = await firstValueFrom(
this.httpService.get(url, {
params: {
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('开放平台授权失败');
}
}
async refreshAccessToken(refreshToken: string) {
const url = 'https://api.weixin.qq.com/sns/oauth2/refresh_token';
try {
const response = await firstValueFrom(
this.httpService.get(url, {
params: {
appid: process.env.OPEN_PLATFORM_APPID,
grant_type: 'refresh_token',
refresh_token: refreshToken
}
})
);
return response.data;
} catch (error) {
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;
user_ticket?: string;
user_info?: {
userid: string;
name: string;
department: number[];
};
}
@Injectable()
export class EnterpriseWechatAuthService {
constructor(private readonly httpService: HttpService) {}
async getUserInfo(code: string): Promise<EnterpriseWechatAuthResponse> {
const tokenUrl = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken';
const userInfoUrl = 'https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo';
const tokenResponse = await firstValueFrom(
this.httpService.get(tokenUrl, {
params: {
corpid: process.env.ENTERPRISE_CORPID,
corpsecret: process.env.ENTERPRISE_CORPSECRET
}
})
);
const accessToken = tokenResponse.data.access_token;
const userInfoResponse = await firstValueFrom(
this.httpService.get(userInfoUrl, {
params: {
access_token: accessToken,
code: code
}
})
);
return userInfoResponse.data;
}
}
各个平台授权小结
授权类型 | 个人是否可用 | 是否收费 | 主要适用场景 |
---|
网页授权 | 是 | 免费 | 网站、H5应用 |
小程序授权 | 是 | 免费 | 小程序登录、开放平台 |
公众号授权 | 部分可用 | 免费+增值服务 | 公众号相关应用(服务号、订阅号) |
企业微信 | 否 | 有费用 | 企业内部协作 |
转自https://www.cnblogs.com/HaiJun-Aion/p/18609286
该文章在 2024/12/17 15:49:13 编辑过