前言

微信小程序的使用率越来越高咯,必要的就是登陆流程,这个code,那个openid,这一下,那一下,晕了没。让我来给你一些可实施的点子吧!

【注意】const { code } = await Taro.login(); 这个code只能使用一次。登录请求失败后,根据业务逻辑,看看是否要重新获取一次。

微信小程序登录流程涉及前端、后端和微信开放平台的协作

一、微信小程序登录原理

1.前端获取临时凭证(code)

通过 Taro.login() 获取微信临时登录凭证 code

官网链接:https://docs.taro.zone/docs/apis/open-api/login/

// 调用login api,得到code。
Taro.login({
  success: function (res) {
    if (res.code) { // 就是这个code哦~
      //发起网络请求
      Taro.request({
        url: 'https://test.com/onLogin',
        data: {
          code: res.code
        }
      })
    } else {
      console.log('登录失败!' + res.errMsg)
    }
  }
})

2. 发送 code 到后端

code 发送到自己的服务器。

3. 后端换取用户唯一标识

服务器使用 code + 小程序 appId + appSecret 向微信服务器换取 openidsession_key

4. 后端生成自定义登录态

服务器生成自定义登录令牌(如 JWT 或 SessionID),并返回给前端。

5. 前端存储登录态

将服务器返回的令牌存储在本地(如 Storage),后续请求携带该令牌。

二、前端实现步骤

1. 配置微信小程序 AppID

project.config.json 中添加:

{
  "appid": "你的小程序AppID"
}

2. 创建登录 API

这只是举个例子哈,按照后端老师的接口对接就ok,在 src/api/auth.js 中:

import request from '@/utils/request';

// 登录接口
export function loginByWechat(data) {
  return request({
    url: '/api/auth/wechat',
    method: 'POST',
    data
  });
}

// 获取用户信息
export function getUserInfo() {
  return request({
    url: '/api/user/info',
    method: 'GET'
  });
}

3. 封装登录逻辑

src/utils/auth.js 中:

import Taro from '@tarojs/taro';
import { loginByWechat, getUserInfo } from '@/api/auth';

// 登录流程
export async function login() {
  try {
    // 1. 获取微信登录凭证
    const { code } = await Taro.login();
    
    // 2. 发送凭证到服务器
    const res = await loginByWechat({ code });
    
    // 3. 存储登录态
    Taro.setStorageSync('token', res.token);
    Taro.setStorageSync('userInfo', res.userInfo);
    
    return res.userInfo;
  } catch (error) {
    console.error('登录失败', error);
    throw error;
  }
}

// 检查登录状态
export function checkLogin() {
  const token = Taro.getStorageSync('token');
  return !!token;
}

// 登出
export function logout() {
  Taro.removeStorageSync('token');
  Taro.removeStorageSync('userInfo');
}

4. 创建登录页面

这里根据需求,常见的有两种:

官网文章路径: https://developers.weixin.qq.com/miniprogram/dev/component/button.html

1)点击获取个人信息,微信一键登录。

使用<button>open-type="getUserInfo"
在这里插入图片描述
src/pages/login/index.vue 中:

<template>
  <view class="login-container">
    <view class="logo">微信登录示例</view>
    <button class="login-btn" open-type="getUserInfo" @getuserinfo="onGetUserInfo">
      微信一键登录
    </button>
  </view>
</template>

<script setup>
import { ref } from 'vue';
import Taro from '@tarojs/taro';
import { login } from '@/utils/auth';

const loading = ref(false);

const onGetUserInfo = async (e) => {
  if (!e.detail.userInfo) {
    Taro.showToast({ title: '授权失败', icon: 'none' });
    return;
  }
  
  loading.value = true;
  try {
    await login();
    Taro.showToast({ title: '登录成功' });
    
    // 登录成功后跳转
    const redirectUrl = Taro.getStorageSync('redirectUrl') || '/pages/index/index';
    Taro.removeStorageSync('redirectUrl');
    
    if (redirectUrl === '/pages/login/index') {
      Taro.switchTab({ url: '/pages/index/index' });
    } else {
      Taro.redirectTo({ url: redirectUrl });
    }
  } catch (error) {
    Taro.showToast({ title: '登录失败', icon: 'none' });
  } finally {
    loading.value = false;
  }
};
</script>
2)获取手机号登录

具体代码就不贴出来啦~ 如果有同学觉得不太清楚,问的多了我再写出来吧。

大概的思路如下图:
大概思路就是:点击授权手机号 --> 将code(login api接口返回),encryptedData、iv(获取手机号方法返回)传给后端 --> 后端老师处理返回需要的参数(手机号码,access_token等)
在这里插入图片描述

<template>
  <view class="login-container">
    <view class="logo">微信登录示例</view>
	<button size="large" open-type="getPhoneNumber" :customStyle="btn_style" color="#222222"
			text="手机号快捷登录" @getphonenumber="wxLogin" ></button>
  </view>
</template>
5. 请求拦截器配置

详细的请求会在另一篇文章里说明,后面整理出来之后会链过来滴。

不白来,都不白来 ☺

这边就举个例子,在 src/utils/request.js 中:

// 添加请求拦截器
service.interceptors.request.use(
  (config) => {
    const token = Taro.getStorageSync('token');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  (error) => {
    console.error('请求错误', error);
    return Promise.reject(error);
  }
);

// 添加响应拦截器
service.interceptors.response.use(
  (response) => {
    return response.data;
  },
  (error) => {
    // 处理 401 未授权状态
    if (error.response && error.response.status === 401) {
      Taro.removeStorageSync('token');
      Taro.removeStorageSync('userInfo');
      
      // 记录当前页面,登录后跳转回来
      const pages = Taro.getCurrentPages();
      const currentPage = pages[pages.length - 1];
      const redirectUrl = `/${currentPage.route}`;
      Taro.setStorageSync('redirectUrl', redirectUrl);
      
      // 跳转到登录页
      Taro.navigateTo({ url: '/pages/login/index' });
    }
    return Promise.reject(error);
  }
);

三、后端接口示例(Node.js + Express)

这个仅供参考哈,具体的后端实现代码,交给伟大的后端老师们吧

const express = require('express');
const axios = require('axios');
const jwt = require('jsonwebtoken');
const router = express.Router();

// 微信小程序配置
const WX_CONFIG = {
  appId: '你的小程序AppID',
  appSecret: '你的小程序AppSecret'
};

// 微信登录接口
router.post('/wechat', async (req, res) => {
  try {
    const { code } = req.body;
    
    // 1. 向微信服务器换取 openid 和 session_key
    const wxRes = await axios.get('https://api.weixin.qq.com/sns/jscode2session', {
      params: {
        appid: WX_CONFIG.appId,
        secret: WX_CONFIG.appSecret,
        js_code: code,
        grant_type: 'authorization_code'
      }
    });
    
    const { openid, session_key } = wxRes.data;
    
    // 2. 查找或创建用户
    let user = await User.findOne({ openid });
    if (!user) {
      user = await User.create({ openid });
    }
    
    // 3. 生成 JWT 令牌
    const token = jwt.sign(
      { userId: user._id, openid },
      '你的JWT密钥',
      { expiresIn: '7d' }
    );
    
    // 4. 返回用户信息和令牌
    res.json({
      code: 200,
      message: '登录成功',
      data: {
        token,
        userInfo: {
          id: user._id,
          openid: user.openid,
          nickname: user.nickname,
          avatar: user.avatar
        }
      }
    });
  } catch (error) {
    console.error('微信登录错误', error);
    res.status(500).json({ code: 500, message: '服务器错误' });
  }
});

// 获取用户信息接口(需要授权)
router.get('/info', async (req, res) => {
  try {
    // 从请求头中获取令牌
    const token = req.headers.authorization?.replace('Bearer ', '');
    if (!token) {
      return res.status(401).json({ code: 401, message: '未授权' });
    }
    
    // 验证令牌
    const decoded = jwt.verify(token, '你的JWT密钥');
    const user = await User.findById(decoded.userId);
    
    if (!user) {
      return res.status(401).json({ code: 401, message: '用户不存在' });
    }
    
    res.json({
      code: 200,
      message: '获取成功',
      data: {
        id: user._id,
        nickname: user.nickname,
        avatar: user.avatar
      }
    });
  } catch (error) {
    console.error('获取用户信息错误', error);
    res.status(500).json({ code: 500, message: '服务器错误' });
  }
});

module.exports = router;

四、微信小程序配置

1. 获取 AppID 和 AppSecret

在微信公众平台(https://mp.weixin.qq.com)获取。

AppSecret 要记得直接复制,发送给后端老师,你在微信公众平台生成一次之后,不会在列表上展示出来,只能重置哦。
在这里插入图片描述

2. 配置服务器域名

在小程序管理后台配置合法域名:

  • 开发设置 → 服务器配置 → 接口域名
  • 添加 https://api.weixin.qq.com(用于登录)和你的服务器域名。
    在这里插入图片描述

六、完整登录流程调用

  1. 用户点击登录按钮 → 触发 onGetUserInfo 方法
  2. 前端获取 code → 调用 Taro.login()
  3. 发送 code 到后端 → 调用 loginByWechat API
  4. 后端验证 code → 获取 openidsession_key
  5. 后端生成 token → 返回给前端
  6. 前端存储 token → 跳转到目标页面
  7. 后续请求携带 token → 通过请求拦截器自动添加
  8. 处理 token 失效 → 通过响应拦截器检测 401 状态,跳转到登录页

七、注意事项

1. 安全性

  • 敏感接口必须验证 token
  • 不要在前端暴露 appSecret
  • 使用 HTTPS 协议

2. 用户体验

  • 登录状态持久化(Storage)
  • 登录后跳转到之前的页面
  • 提供登出功能

3. 调试技巧

  • 使用微信开发者工具的 “API 调试” 功能
  • 后端打印日志跟踪登录流程
  • 使用抓包工具(如 Charles)分析请求

通过以上步骤,你可以实现一个完整的 Taro 3 + Vue 3 微信小程序登录流程,包括用户授权、登录态管理、权限控制和错误处理。

更多推荐