Files
ShaFaFanXin/后端/WECHAT_INTEGRATION.md
2026-01-27 18:06:04 +08:00

5.6 KiB
Raw Permalink Blame History

微信小程序接入指南

后端API接口

1. 微信小程序登录

接口地址: POST /api/auth/wechat/login

请求体:

{
  "wechatLogin": {
    "code": "微信小程序wx.login()获取的code"
  },
  "userInfo": {
    "nickName": "用户昵称",
    "avatarUrl": "用户头像URL"
  }
}

响应:

{
  "user": {
    "id": 1,
    "username": "wx_12345678",
    "email": "openid@wechat.local",
    "realName": "用户昵称",
    "avatar": "用户头像URL",
    "role": "customer",
    "status": "active"
  },
  "access_token": "JWT访问令牌",
  "refresh_token": "JWT刷新令牌"
}

前端集成示例uni-app

1. 登录页面代码示例

<template>
  <view class="login-container">
    <button @click="wxLogin" class="wx-login-btn">微信登录</button>
  </view>
</template>

<script>
export default {
  methods: {
    // 微信登录
    async wxLogin() {
      try {
        // 1. 获取微信登录code
        const loginRes = await uni.login({
          provider: 'weixin'
        });
        
        if (loginRes[1].code) {
          // 2. 获取用户信息(可选)
          const userInfo = await this.getUserInfo();
          
          // 3. 发送到后端登录
          const response = await uni.request({
            url: 'http://localhost:3000/api/auth/wechat/login',
            method: 'POST',
            data: {
              wechatLogin: {
                code: loginRes[1].code
              },
              userInfo: userInfo
            }
          });
          
          if (response[1].statusCode === 200) {
            const { user, access_token, refresh_token } = response[1].data;
            
            // 4. 保存用户信息和token
            uni.setStorageSync('access_token', access_token);
            uni.setStorageSync('refresh_token', refresh_token);
            uni.setStorageSync('userInfo', user);
            
            // 5. 跳转到首页
            uni.switchTab({
              url: '/pages/index/index'
            });
          }
        }
      } catch (error) {
        console.error('登录失败:', error);
        uni.showToast({
          title: '登录失败',
          icon: 'none'
        });
      }
    },
    
    // 获取用户信息(可选)
    async getUserInfo() {
      try {
        const userProfile = await uni.getUserProfile({
          desc: '用于完善用户资料'
        });
        
        return {
          nickName: userProfile[1].userInfo.nickName,
          avatarUrl: userProfile[1].userInfo.avatarUrl
        };
      } catch (error) {
        console.log('用户拒绝授权用户信息');
        return null;
      }
    }
  }
}
</script>

<style>
.login-container {
  padding: 40px;
  text-align: center;
}

.wx-login-btn {
  background-color: #07c160;
  color: white;
  border: none;
  padding: 12px 24px;
  border-radius: 4px;
  font-size: 16px;
}
</style>

2. API请求拦截器

// utils/request.js
const BASE_URL = 'http://localhost:3000/api';

// 请求拦截器
uni.addInterceptor('request', {
  invoke(args) {
    // 添加基础URL
    if (!args.url.startsWith('http')) {
      args.url = BASE_URL + args.url;
    }
    
    // 添加认证头
    const token = uni.getStorageSync('access_token');
    if (token) {
      args.header = {
        ...args.header,
        'Authorization': `Bearer ${token}`
      };
    }
    
    return args;
  },
  
  success(result) {
    // 处理认证失败
    if (result.statusCode === 401) {
      // Token过期尝试刷新或跳转登录
      uni.removeStorageSync('access_token');
      uni.removeStorageSync('userInfo');
      uni.reLaunch({
        url: '/pages/login/login'
      });
    }
    
    return result;
  }
});

export default {
  // 封装请求方法
  request(options) {
    return uni.request({
      ...options,
      header: {
        'Content-Type': 'application/json',
        ...options.header
      }
    });
  }
}

3. 用户信息获取

// pages/profile/profile.vue
export default {
  data() {
    return {
      userInfo: {}
    };
  },
  
  onLoad() {
    this.getUserProfile();
  },
  
  methods: {
    async getUserProfile() {
      try {
        const response = await uni.request({
          url: '/users/profile',
          method: 'GET'
        });
        
        if (response[1].statusCode === 200) {
          this.userInfo = response[1].data;
        }
      } catch (error) {
        console.error('获取用户信息失败:', error);
      }
    }
  }
}

配置说明

1. 后端环境配置

.env 文件中配置微信小程序信息:

# 微信小程序配置
WECHAT_APPID=你的小程序AppID
WECHAT_SECRET=你的小程序AppSecret

2. 微信小程序配置

manifest.json 中配置微信小程序:

{
  "mp-weixin": {
    "appid": "你的小程序AppID",
    "setting": {
      "urlCheck": false
    },
    "requiredPrivateInfos": ["getUserProfile"]
  }
}

3. 请求域名配置

在微信小程序后台配置服务器域名:

  • 开发环境: http://localhost:3000
  • 生产环境: https://yourdomain.com

注意事项

  1. 获取微信AppID和AppSecret

    • 登录微信小程序后台
    • 在"开发" -> "开发管理" -> "开发设置"中获取
  2. 用户信息授权

    • getUserProfile 需要用户主动触发
    • 建议在用户首次登录时请求
  3. Token管理

    • 访问令牌有效期7天
    • 刷新令牌有效期30天
    • 建议在请求拦截器中处理token刷新
  4. 安全考虑

    • AppSecret不要泄露到前端
    • 生产环境使用HTTPS
    • 定期更换JWT密钥