在原生微信小程序中获取用户的手机号并存储需要通过微信提供的wx.login
和wx.getUserProfile
接口来完成。这些接口允许小程序获取用户信息并在用户授权后获取其手机号。以下是一个详细的实现示例和相应的代码注释。
1. 配置小程序的权限
在实现获取手机号功能之前,需要确保小程序有获取用户信息和手机号的权限。在app.json
文件中添加如下代码:
{ "pages": [ "pages/index/index" ], "permission": { "scope.userInfo": { "desc": "获取用户信息以便更好地提供服务" }, "scope.userPhoneNumber": { "desc": "获取用户手机号以便更好地提供服务" } } }
2. 登录并获取临时登录凭证(code)
首先,需要调用wx.login
接口获取用户的临时登录凭证code
,然后使用这个code
去换取用户的session_key,这是后续解密用户手机号的关键。以下是在index.js
中的实现:
Page({ data: { userInfo: null, hasUserInfo: false, canIUseGetUserProfile: false, phoneNumber: '' }, onLoad() { // 判断是否可以使用getUserProfile if (wx.getUserProfile) { this.setData({ canIUseGetUserProfile: true }) } }, getUserProfile(e) { wx.getUserProfile({ desc: '用于完善用户资料', success: (res) => { this.setData({ userInfo: res.userInfo, hasUserInfo: true }) this.getPhoneNumber(); } }) }, getPhoneNumber() { wx.login({ success: res => { const code = res.code; // 发送code到后台换取 openId, sessionKey, unionId if (code) { wx.request({ url: 'https://yourserver.com/onLogin', method: 'POST', data: { code: code }, success: function (res) { if (res.statusCode === 200) { // 成功获取 session_key 等信息 wx.setStorageSync('sessionKey', res.data.sessionKey); } else { console.error('登录失败!', res.errMsg); } }, fail: function (err) { console.error('请求失败!', err); } }); } else { console.error('登录失败!', res.errMsg); } } }); } })
3. 获取手机号并存储
接下来,当用户点击按钮授权获取手机号时,需要调用wx.getUserProfile接口获取用户的基本信息,然后通过微信提供的按钮组件<button open-type="getPhoneNumber">来获取用户的手机号。以下是在index.wxml和index.js中的实现:
index.wxml
:
<view class="container"> <button wx:if="{{canIUseGetUserProfile}}" bindtap="getUserProfile">获取用户信息</button> <button wx:if="{{hasUserInfo}}" open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">获取手机号</button> </view>
index.js
:
Page({ data: { userInfo: null, hasUserInfo: false, canIUseGetUserProfile: false, phoneNumber: '' }, onLoad() { if (wx.getUserProfile) { this.setData({ canIUseGetUserProfile: true }) } }, getUserProfile(e) { wx.getUserProfile({ desc: '用于完善用户资料', success: (res) => { this.setData({ userInfo: res.userInfo, hasUserInfo: true }) } }) }, getPhoneNumber(e) { if (e.detail.errMsg === 'getPhoneNumber:ok') { const encryptedData = e.detail.encryptedData; const iv = e.detail.iv; const sessionKey = wx.getStorageSync('sessionKey'); // 发送数据到后台解密 wx.request({ url: 'https://yourserver.com/decryptData', method: 'POST', data: { encryptedData: encryptedData, iv: iv, sessionKey: sessionKey }, success: res => { if (res.statusCode === 200) { // 成功获取手机号 this.setData({ phoneNumber: res.data.phoneNumber }); } else { console.error('解密失败!', res.errMsg); } }, fail: err => { console.error('请求失败!', err); } }); } else { console.error('用户拒绝授权获取手机号'); } } })
4. 后端服务接口
前端代码中的请求需要后台服务配合进行解密操作。以下是一个简单的Node.js后端服务示例,使用了axios
和crypto
模块:
const express = require('express'); const axios = require('axios'); const crypto = require('crypto'); const app = express(); app.use(express.json()); const appId = 'yourAppId'; const appSecret = 'yourAppSecret'; app.post('/onLogin', async (req, res) => { const code = req.body.code; try { const response = await axios.get(`https://api.weixin.qq.com/sns/jscode2session`, { params: { appid: appId, secret: appSecret, js_code: code, grant_type: 'authorization_code' } }); res.json(response.data); } catch (error) { res.status(500).json({ error: error.message }); } }); app.post('/decryptData', (req, res) => { const { encryptedData, iv, sessionKey } = req.body; try { const decodedData = decryptData(appId, sessionKey, encryptedData, iv); res.json(decodedData); } catch (error) { res.status(500).json({ error: error.message }); } }); function decryptData(appId, sessionKey, encryptedData, iv) { const sessionKeyBuffer = Buffer.from(sessionKey, 'base64'); const encryptedDataBuffer = Buffer.from(encryptedData, 'base64'); const ivBuffer = Buffer.from(iv, 'base64'); const decipher = crypto.createDecipheriv('aes-128-cbc', sessionKeyBuffer, ivBuffer); decipher.setAutoPadding(true); let decoded = decipher.update(encryptedDataBuffer, 'binary', 'utf8'); decoded += decipher.final('utf8'); const decodedData = JSON.parse(decoded); if (decodedData.watermark.appid !== appId) { throw new Error('Invalid Buffer'); } return decodedData; } app.listen(3000, () => { console.log('Server is running on port 3000'); });
5. 测试和调试
最后,确保你的前后端代码都已正确配置和部署,并在微信开发者工具中进行测试。通过点击按钮授权获取用户信息和手机号,并在控制台查看相应的日志输出。
这样,你就完成了在原生微信小程序中获取用户手机号并存储的功能。如果你有任何疑问或需要进一步的帮助,请随时向我提问。