初始化参股
This commit is contained in:
278
后端/WECHAT_INTEGRATION.md
Normal file
278
后端/WECHAT_INTEGRATION.md
Normal file
@@ -0,0 +1,278 @@
|
||||
# 微信小程序接入指南
|
||||
|
||||
## 后端API接口
|
||||
|
||||
### 1. 微信小程序登录
|
||||
|
||||
**接口地址**: `POST /api/auth/wechat/login`
|
||||
|
||||
**请求体**:
|
||||
```json
|
||||
{
|
||||
"wechatLogin": {
|
||||
"code": "微信小程序wx.login()获取的code"
|
||||
},
|
||||
"userInfo": {
|
||||
"nickName": "用户昵称",
|
||||
"avatarUrl": "用户头像URL"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**响应**:
|
||||
```json
|
||||
{
|
||||
"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. 登录页面代码示例
|
||||
|
||||
```vue
|
||||
<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请求拦截器
|
||||
|
||||
```javascript
|
||||
// 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. 用户信息获取
|
||||
|
||||
```javascript
|
||||
// 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` 文件中配置微信小程序信息:
|
||||
|
||||
```env
|
||||
# 微信小程序配置
|
||||
WECHAT_APPID=你的小程序AppID
|
||||
WECHAT_SECRET=你的小程序AppSecret
|
||||
```
|
||||
|
||||
### 2. 微信小程序配置
|
||||
|
||||
在 `manifest.json` 中配置微信小程序:
|
||||
|
||||
```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密钥
|
||||
Reference in New Issue
Block a user