首页 > 其他分享 >微信授权全链路打通指南

微信授权全链路打通指南

时间:2024-12-16 09:58:01浏览次数:8  
标签:指南 code string 微信 access token 链路 授权

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

微信小程序授权

image

image

授权流程:

  1. 用户在小程序中点击登录按钮,触发 wx.login() 获取 code
  2. 小程序将 code 发送到后端服务器。
  3. 后端通过微信接口 jscode2session 使用 code 获取 session_keyopenid
  4. 后端返回 session_keyopenid 给前端。
  5. 前端获取 session_keyopenid,使用 wx.getUserProfile() 获取用户信息(如昵称、头像等)。
  6. 如果需要,可以将用户信息(如昵称、头像等)发送到后端进行存储或处理。
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) {
      // 实现微信小程序用户信息解密逻辑
      // 通常需要使用第三方加密库如 crypto-js
    }
  }

微信网页授权(OAuth 2.0)

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

image

image

授权流程

  1. 发起授权
    • 用户点击登录/授权按钮
    • 生成授权链接
    • 跳转至微信授权页面
  2. 用户确认
    • 用户选择是否授权
    • 确认后获取临时授权码 code
  3. 换取 Access Token
    • 服务端使用 code 换取 access_token
    • 获取用户的 openidaccess_token
  4. 获取用户信息
    • 使用 access_tokenopenid
    • 调用微信接口获取用户详细信息
  5. 系统内部处理
    • 创建或更新用户信息
    • 生成系统内部登录态
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<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('获取用户信息失败');
    }
  }
}

微信开放平台授权

image

特点:

  • 适用于第三方应用
  • 支持移动应用、网站应用等
  • 需要开发者资质认证
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<OpenPlatformAuthResponse> {
    // 微信获取 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

image

特点:

  • 主要面向企业内部应用
  • 更强的权限控制
  • 安全性更高

授权流程

  1. 发起授权
    • 员工访问企业内部应用
    • 触发登录机制(扫码/输入)
    • 生成企业微信授权链接
  2. 身份验证
    • 跳转企业微信登录页
    • 员工确认身份
    • 获取临时授权码
  3. 换取用户信息
    • 服务端使用 code 换取用户标识
    • 获取 userid
    • 调用接口获取用户详细信息
  4. 系统内部处理
    • 验证员工身份
    • 检查权限状态
    • 生成系统内部登录态
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<EnterpriseWechatAuthResponse> {
    // 获取企业 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应用
小程序授权 免费 小程序登录、开放平台
公众号授权 部分可用 免费+增值服务 公众号相关应用(服务号、订阅号)
企业微信 有费用 企业内部协作

image

标签:指南,code,string,微信,access,token,链路,授权
From: https://www.cnblogs.com/HaiJun-Aion/p/18609286

相关文章

  • 织梦怎么修改网站文字,织梦CMS网站文字修改指南
    在织梦CMS中修改网站文字通常涉及编辑模板文件或内容管理模块。以下是详细的步骤:登录后台管理系统:使用管理员账号登录织梦CMS的后台管理系统。编辑模板文件:进入“模板”->“默认模板管理”。找到需要修改的模板文件,通常是index.htm或其他相关的HTML文件。打开模板......
  • 网站主页修改方案怎么写,网站主页修改方案编写指南
    编写网站主页修改方案需要详细规划和描述修改的具体内容和步骤。以下是详细的步骤和建议:确定修改目标:明确修改的目的和预期效果。例如,提升用户体验、增加转化率等。分析现状:分析当前主页存在的问题和不足。收集用户反馈和数据分析结果。设计新主页:设计新的主页......
  • Easysearch Java SDK 2.0.x 使用指南(一)
    各位Easysearch的小伙伴们,我们前一阵刚把easysearch-client更新到了2.0.2版本!借此详细介绍下新版客户端的使用。新版客户端和1.0版本相比,完全重构,抛弃了旧版客户端的一些历史包袱,从里到外都焕然一新!不管是刚入门的小白还是经验丰富的老司机,2.0.x客户端都能让你开发效率......
  • Windows 应用程序图标设置完全指南
    目录简介图标基础知识实现方案代码实现常见问题最佳实践进阶技巧简介在Windows应用程序开发中,正确设置应用程序图标是提升用户体验的重要环节。一个应用程序的图标会出现在多个位置:任务栏窗口标题栏系统托盘开始菜单文件资源管理器每个位置都有其特定的要求......
  • 基于微信小程序的医院挂号预约系统
    文章目录详细视频演示项目介绍技术介绍功能介绍核心代码系统效果图文章目录源码获取详细视频演示文章底部名片,获取项目的完整演示视频,免费解答技术疑问项目介绍  现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处......
  • 基于微信小程序的医院设备报修管理系统设计与实现(源码+lw+部署+讲解)
    文章目录1.前言2.详细视频演示3具体实现截图3.1小程序端部分效果3.2后台管理端部分效果4.技术可行性分析5.技术简介5.1后端框架SpringBoot5.2微信小程序5.3系统开发平台6.业务流程分析7.代码参考8.数据库参考9.为什么选择我们10.源码及文档获取1.前言博主介绍:✌C......
  • 带你实现 HarmonyOS Next 微信聊天 02
    带你实现HarmonyOSNext微信聊天02接上一篇前言代码会统一放在码云上案例目标这个是安卓手机上的真正的微信聊天界面功能效果实际效果案例功能上一篇,已经实现了以下功能页面沉浸式聊天内容滚动输入框状态切换聊天信息框宽度自适应输入法避让canvas......
  • 带你实现 HarmonyOS Next 微信聊天 01
    带你实现HarmonyOSNext微信聊天01前言代码会统一放在码云上,纯静态的完整代码会放在末尾案例目标这个是安卓手机上的真正的微信聊天界面功能效果实际效果案例功能页面沉浸式聊天内容滚动输入框状态切换聊天信息框宽度自适应输入法避让语音消息根据时长自动宽......
  • C#/.NET/.NET Core 学习、工作、面试指南
    现如今网上关于Java、前端、Android、Golang...等相关技术的学习资料、工作心得、面试指南一搜都是一大把,但是咱们C#/.NET的相关学习资料、工作心得、面试指南都是寥寥无几。我在微信技术群、知乎里面经常会看到这样的提问:有没有好的C#/.NET相关的学习书籍、视频教程、项目框架和......
  • 基于java+Springboot+MySQL微信小程序的大用户心理咨询系统设计与实现99040-计算机原
    目录1绪论1.1研究背景1.2研究现状1.3论文结构与章节安排2 基于微信小程序的大用户心理咨询系统设计与实现分析2.1可行性分析2.2系统功能分析2.3 系统用例分析2.4系统流程分析2.5本章小结3基于微信小程序的大用户心理咨询系统设计与实现总体设计......