当前位置: 首页 > news >正文

【微信小程序 + 登录流程】微信小程序授权登录完整流程,一篇搞定!(含代码实现) - 详解

前言

只要开始写一个微信小程序,必要的登录流程每次都要再理一下逻辑,记录一下思路,以便于后面自己食用。
大家有什么更好的思路可以分享~后面想创建一个学习小组,有兴趣的小伙伴可以联系我。

一、小程序微信授权登录

在这里插入图片描述

1.登录态检查(节点 B)
2.获取临时凭证 code(节点 D)
  • 操作方:小程序前端
  • 核心接口wx.login()
  • 说明
    • 调用后微信客户端会向微信服务器请求,返回一个 一次性、有效期 5 分钟 的 code(临时登录凭证,仅能使用 1 次);
    • 此步骤 无需用户手动授权(静默获取,不弹授权弹窗)。

文档直通车: 开放接口/登录/wx.login

3. 开发者服务器换用户标识(节点 F-G)
  • 操作方:开发者服务器
  • 核心接口:微信官方 auth.code2Session 接口(GET 请求)
  • 请求参数(必须包含)
参数名来源说明
appid小程序管理后台获取小程序唯一标识
secret小程序管理后台获取小程序密钥(需保密,不可暴露在前端)
js_code前端传递的 code临时登录凭证
grant_type固定值"authorization_code"
  • 返回结果(微信服务器返回给开发者服务器)
    • openid:用户在当前小程序的 唯一标识(每个用户对每个小程序的 openid 不同);
    • session_key:微信服务器与开发者服务器之间的 加密密钥(用于解密用户敏感信息,如手机号、头像昵称,需保密存储);
    • code 无效(如过期、重复使用),会返回错误码(如 40029)。

在这里插入图片描述

文档直通车: 小程序登录/小程序登录

4. 生成自定义登录态(节点 H)
  • 操作方:开发者服务器
  • 核心目的:避免直接使用 openid/session_key 传输,提升安全性
  • 常见方案
    • openid 查询数据库,判断是否为新用户(新用户则创建用户记录,老用户则更新 session_key);
    • 生成自定义登录态(如 JWT Token、随机字符串),并将 Tokenopenidsession_key 关联存储(如存入 RedisMySQL);
    • Token 需设置有效期(如 7 天),过期后需重新登录。
5.登录态存储与使用(节点 J-L)
  • 前端存储:用 wx.setStorageSync('token', 开发者返回的 Token) 保存到本地,下次打开小程序时可直接读取;
  • 后续请求:前端发起业务请求(如 “获取我的订单”)时,在请求头(如 Authorization: Bearer Token)或参数中携带 Token
  • 服务器验证:开发者服务器接收请求后,先验证 Token 有效性(如检查 Token 是否存在、是否过期),验证通过则返回数据,否则返回 “登录失效”,前端需重新触发登录流程。

二、 需用户信息授权(如获取头像、昵称)

在这里插入图片描述
注意:微信已废弃旧的 wx.getUserInfo() 接口,当前需用 wx.getUserProfile() 且必须用户手动点击 “允许” 才能获取信息,不可静默授权。

文档直通车: 开放接口 /用户信息 /wx.getUserProfile

三、小程序获取手机号登录

在这里插入图片描述

1. 前置:获取临时登录凭证 code(节点 D)
2. 触发手机号授权(节点 E-F)

在这里插入图片描述

文档直通车: 表单组件 /button

<!-- WXML --><buttonopen-type="getPhoneNumber"bindgetphonenumber="handleGetPhoneNumber">用手机号登录
</button>
  • 用户交互:点击按钮后,微信会弹出系统弹窗(“允许小程序获取你的手机号?”),用户需手动选择「允许」或「拒绝」,不可静默获取。
3. 获取加密手机号数据(节点 H)
  • 操作方:小程序前端
  • 触发事件:用户同意授权后,会触发 bindgetphonenumber 事件,回调参数中包含加密的手机号信息:
// 前端 JS
handleGetPhoneNumber(e) {
if (e.detail.errMsg === "getPhoneNumber:ok") {
// 用户同意授权,获取加密数据
const encryptedData = e.detail.encryptedData; // 加密的手机号数据
const iv = e.detail.iv; // 解密所需的初始向量
// 后续将 encryptedData、iv 与 code 一起发送给服务器
} else {
// 用户拒绝授权,提示并返回
wx.showToast({ title: "需授权手机号才能登录", icon: "none" });
}
}
  • 关键说明encryptedDataiv 是加密后的字符串,前端无法解密,必须传给开发者服务器,用 session_key 解密。
4. 服务器解密手机号(节点 J-L)
  • 操作方:开发者服务器
  • 核心步骤
    • 换取 session_key:用前端传的 code,调用微信 auth.code2Session 接口(参数含 appidappsecretcode),获取 openid(用户唯一标识)和 session_key(解密密钥);
    • 解密手机号:用 session_keyivencryptedData 进行解密(需用微信官方推荐的加密库,如 Node.jscrypto 模块,JavaAES 解密工具);
  • 解密结果:解密后会得到包含手机号的 JSON 数据,示例:
{
"phoneNumber": "13800138000", // 用户手机号(核心信息)
"purePhoneNumber": "13800138000",
"countryCode": "86" // 国家码
}
5. 关联用户与生成登录态(节点 M)
  • 操作方:开发者服务器
  • 核心逻辑
    • 用户关联:用解密后的手机号(或 openid)查询数据库,判断是否为新用户:
      • 新用户:创建用户记录,存储手机号、openid 等信息;
      • 老用户:更新用户的 session_key(若已过期),关联已有账号;
    • 生成登录态:创建自定义登录态(如 JWT Token、随机字符串),设置有效期(如 7 天),并将 Token 与用户信息关联存储(如 RedisMySQL);
  • 安全注意session_key 和手机号属于敏感信息,不可返回给前端,仅在服务器端存储和使用。
6. 登录态存储与后续使用(节点 N-P)
  • 前端存储:接收服务器返回的 Token,用 wx.setStorageSync('token', Token) 保存到本地,下次打开小程序时直接读取;
  • 后续请求:发起业务请求(如 “查询我的订单”)时,在请求头(如 Authorization: Token xxx)携带 Token
  • 服务器验证:服务器接收请求后,验证 Token 有效性(是否存在、是否过期),通过则返回数据,否则提示 “登录失效”,触发重新登录。

四、具体代码实现

1.需求示例

一般登录按钮会有两种方式出现:

  • 单独的页面(项目logo、登录、取消)
    在这里插入图片描述

  • 一个公共弹框(从页面底部或中间弹出授权弹框)
    在这里插入图片描述

2.代码实现(这里以页面上显示登录按钮为例)

在这里插入图片描述

<template><view class="demo-login-container"><button class="btn" open-type="getPhoneNumber" @getphonenumber="getphonenumber">手机号快捷登录</button><view class="black2 font28 mt28" @click="cancelLogin">取消登录</view></view></template><script lang="ts" setup>import Taro from '@tarojs/taro'import loginService from "../../server/login/loginService"// // 获取codeconst getCode = async () => {const { code } = await Taro.login()Taro.setStorageSync('code', code)}const getphonenumber = async(e) => {console.log("getphonenumber -------- e", e);console.log("pageObj.code", Taro.getStorageSync('code'));let { encryptedData, iv } = e.detail;console.log("encryptedData-------------------------", encryptedData, iv);if (!iv) return;try {let res;// 将code 、 encryptedData、iv 发送到服务器res = await loginService.login({ code: Taro.getStorageSync('code'), encryptedData, iv });console.log("res", res);// 登录成功处理Taro.setStorageSync('token', res.data.access_token);Taro.setStorageSync('userInfo', res.data.user_info);// 一些你的逻辑,比如页面跳转:// Taro.switchTab({//   url: '/pages/index/index'// })} catch (error) {console.error('登录失败:', error);Taro.showToast({title: error.message || '登录失败',icon: 'none'});getCode()}};const cancelLogin = () => {Taro.showToast({title: '取消登录',icon: 'none'})}</script><style lang="scss">.demo-login-container {width: 100%;display: flex;flex-direction: column;align-items: center;.btn {width: 600rpx;height: 80rpx;background-color: #4ea311;color: #fff;font-size: 32rpx;border-radius: 40rpx;text-align: center;}}</style>

我的项目框架为Taro,Uniapp和小程序原生也适用,改为对应的api就行

五、关键注意事项

1.解密失败排查:

若解密失败,常见原因:session_key 过期(wx.login() 需重新调用获取新codesession_key)、encryptedData/iv 传输错误、appid/appsecret 配置错误;
在这里插入图片描述

2.用户拒绝授权处理:

需友好提示 “授权手机号是登录必要条件”,并提供重新授权入口(不可强制拦截用户);

注意
小程序审核是要求,用户能取消登录的,所以大家在做登录时,不能强制用户登录

3.安全性要求:

appsecretsession_key 必须在服务器端存储,严禁暴露在前端代码中(防止被窃取后解密用户手机号);

建议对前端与服务器的通信采用 HTTPS 协议,避免数据传输被劫持。

http://www.jsqmd.com/news/43830/

相关文章:

  • linux auto
  • 记录相关的操作
  • P9846 [ICPC 2021 Nanjing R] Paimons Tree
  • linux audio
  • 不同方向的箭头符号
  • 11.13 表子查询 内连接补充 事务
  • Elasticsearch 7.17 集群添加账号密码
  • 深入解析:推荐给硬件工程师的技术书籍
  • 全球可观测厂商怎么选?2025年可观测性平台深度分析
  • 2025 ICPC 沈阳区域赛 游记
  • 在树莓派中配置X11桌面的HDMI配置
  • 2025年最新苗木批发基地综合实力排行榜单,国槐/樱花/红叶李/苗木/金叶复叶槭/红叶石楠/丝棉木/油松/白蜡/金叶女贞/紫薇种植推荐
  • 2025 最新移动厕所源头厂家推荐:千台设备储备 + 全国服务网点,国际测评认证优质品牌榜单工地临时/户外移动厕所出租/移动公厕租赁/出租移动厕所公司推荐
  • 透视数字世界:可观测平台如何破解企业智能运维困局
  • kotlin中HorizontalDivider() ModalBottomSheet background()
  • 2025 履带厂家最新推荐排行榜:聚焦高性能钢制履带与履带板,权威测评优选榜单履带板/履带钢/钢制履带/钢履带/履带型钢公司推荐
  • 11月18号
  • 2025 最新黄锈石实力厂家推荐排行榜:无辐射环保石材权威测评,光面 / 荔枝面 / 路沿石优质供应商精选黄锈石菠萝面/黄锈石滚石/黄锈石蘑菇石公司推荐
  • linux at 脚本
  • 机器学习鼻祖级算法——使用SVM实现多分类及Python实现 - 指南
  • 城市生命线安全专项应用系统--供水管网安全监测环境
  • linux asp.net
  • 什么是可观测性?数字化转型时代的企业“透视眼”
  • 2025年苗木批发基地十大诚信批发商排行,青叶复叶槭/红叶李/金叶复叶槭/紫薇/苗木/栾树/白蜡/油松/无刺枸骨球/红叶石楠种植怎么选择
  • 每日 Emacs Tip:Keyboard Macros(键盘宏)——内置小功能详解
  • 每日 Emacs Tip:Emacs Lisp 语法详解 —— 反引用(Backquote)
  • 详细介绍:【物联网架构】
  • 深入解析:FPGA开发入门:深入理解计数器——数字逻辑的时序基石
  • CF1898F Vova Escapes the Matrix
  • 2025年佛山二手房拍卖公司专业推荐指南,佛山二手房拍卖/佛山房屋拍卖全流程服务