微信小程序获取用户手机号存数据库,前后端都有《Java后台版 》

本文分享了微信小程序获取用户手机号并通过Java后台存入数据库的完整流程,包括前端WXML和JS代码,后端Java Controller层及解密、Redis缓存和相关依赖配置。作者特别感谢王子洋的帮助,并推荐了他的博客和B站视频教程《Java开发之旅》。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

开发这个功能的时候走了很多弯路磨了很多时间,我发一下我自己用的来帮助大家

流程图
在这里插入图片描述
前端
index.wxml

    <view>我的首页内容</view>
      <button class='bottom' type='primary' open-type="getUserInfo" lang="zh_CN" bindgetuserinfo="getcode">
            授权获取code
        </button>
     <button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">微信手机号授权登陆</button>

index.js

Page({
  data: {
      //判断小程序的API,回调,参数,组件等是否在当前版本可用。
      canIUse: wx.canIUse('button.open-type.getUserInfo'),
      
      isHide: false
  },



  onLoad: function() {
  
  },
  //获取用户code
  getcode: function(res){
    var that = this;
    // 查看是否授权
    wx.getSetting({
        success: function(res) {
            if (res.authSetting['scope.userInfo']) {
                wx.getUserInfo({
                    success: function(res) {
                        // 用户已经授权过,不需要显示授权页面,所以不需要改变 isHide 的值 根据自己的需求有其他操作再补充 我这里实现的是在用户授权成功后,调用微信的 wx.login 接口,从而获取code
                        wx.login({
                         //  success: res => {
                          // 获取到用户的 code 之后:res.code 可以传给后台,再经过解析获取用户的 openid 代码如下
                             //   wx.login({
                                  success: function (res) {
                                  console.log("用户的code:" + res.code);
                               //     if (res.code) { //使用小程序登录接口完成后端用户登录
                                      wx.request({
                                        url: "填写服务器接口一定要HTTPS的可以去natapp买一个" +"/getOpenid",
                                        data: {
                                          code: res.code,
                                          appid: "自己的APPID",
                                          secret: "自己的APPSECRET",        
                                        },
                                        method:'POST',
                                        header: {
                                        'content-type': 'application/json' // POST请求
                                        },
                                        success: function (res) {
                                          //把openid保存到缓存里
                                          wx.setStorageSync("openid", res.openid);
                                          wx.setStorageSync("session_key", res.session_key);
                                        }
                                      })
                                //     } else {
                                 //      console.log('获取用户登录态失败!' + res.errMsg)
                          
                                   //  }
                                  }
                                });
                         //   }
                       // });
                    }
                });
            } else {
                // 用户没有授权
                // 改变 isHide 的值,显示授权页面
                that.setData({
                  isHide: true
     });
            }
        }
    });
  },
  //获取用户开发信息
  bindGetUserInfo: function(e) {
      if (e.detail.userInfo) {
          //用户按了允许授权按钮
          var that = this;
          // 获取到用户的信息了,打印到控制台上看下
          console.log("用户的信息如下:");
          console.log(e.detail.openid);
          console.log(e.detail.userInfo);
          //授权成功后,通过改变 isHide 的值,让实现页面显示出来,把授权页面隐藏起来
          that.setData({
              isHide: false
          });
      } else {
          //用户按了拒绝按钮
          wx.showModal({
              title: '警告',
              content: '您点击了拒绝授权,将无法进入小程序,请授权之后再进入!!!',
              showCancel: false,
              confirmText: '返回授权',
              success: function(res) {
                  // 用户没有授权成功,不需要改变 isHide 的值
                  if (res.confirm) {
                      console.log('用户点击了“返回授权”');
                  }
              }
          });
      }
  },
//获取用户手机号授权按钮
getPhoneNumber: function (e) {
    var app = getApp();
    wx.request({
      url: "填写服务器接口一定要是HTTPS的可以去natapp买一个" +"/postPhoneNumber",  //解密手机号码接口
      data: {
        encryptedData: e.detail.encryptedData,
        iv: e.detail.iv
      },
      method:'POST',
      header: {
      'content-type': 'application/json' // POST请求
      },

      success: function (res) {
        console.log(res.data.phoneNumber);
        wx.setStorageSync("phonenumber", res.data.phoneNumber);
        
      }
    })
   
  },

})

后端Java代码

Controller层代码

package com.pyx.wechatapplet2.conntroller.wechat;

import com.alibaba.fastjson.JSON;
import com.pyx.wechatapplet2.entity.user.Openid;
import com.pyx.wechatapplet2.util.AesCbcUtil;
import com.pyx.wechatapplet2.util.JDBCUtil;
import com.pyx.wechatapplet2.util.redis.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

@RestController
@Slf4j
public class WechatgetPhone {
    public  String Openid;
    public  String session_key;

    public String getOpenid() {
        return Openid;
    }

    public void setOpenid(String openid) {
        Openid = openid;
    }

    @PostMapping("/getOpenid")
    @Transactional(rollbackFor = Exception.class)
    public synchronized com.alibaba.fastjson.JSONObject getSessionKeyOropenid(@RequestBody Openid openid ) throws Exception {
        System.out.println("Openid code:" + openid.getCode());

        CloseableHttpClient httpclient = HttpClients.createDefault();
        //发送get请求读取调用
### 如何在 UniApp 中获取微信小程序用户手机号并通过 Java 进行解密 #### 获取用户手机号的整体流程 为了实现 UniApp 微信小程序用户手机号的授权以及后端解密功能,可以按照以下逻辑完成: 1. **前端部分 (UniApp)** 在 UniApp 的页面上添加一个 `open-type="getPhoneNumber"` 的按钮组件。当用户点击该按钮时触发回调函数,并将加密数据发送至后端。 2. **后端部分 (Spring Boot)** 后端接收到前端传递的数据后,利用微信开放平台提供的 API 和秘钥对加密数据进行解密,从而获得用户手机号。 --- #### 前端代码示例 (UniApp) 以下是 UniApp 页面中的 HTML 结构和 JavaScript 方法实现: ```html <view class="action-btn"> <button open-type="getPhoneNumber" @getphonenumber="getPhoneNumber" withCredentials="true" class="login-btn cu-btn block bg-blue lg round"> 获取手机号登录 </button> </view> ``` 对应的 Vue.js 方法如下: ```javascript export default { methods: { getPhoneNumber(e) { if (!e.detail.errMsg || e.detail.errMsg !== 'getPhoneNumber:ok') { console.error('用户拒绝提供手机号'); return; } const encryptedData = e.detail.encryptedData; // 加密数据 const iv = e.detail.iv; // 初始化向量 this.$http.post('/api/decryptPhone', { // 调用后端接口 encryptedData, iv }).then(res => { console.log('解密后的手机号:', res.data.phoneNumber); }).catch(err => { console.error('解密失败:', err); }); } } } ``` 上述代码实现了用户点击按钮后,从前端收集加密数据 (`encryptedData` 和 `iv`) 并将其发送给后端的功能[^3]。 --- #### 后端代码示例 (Spring Boot) ##### Controller 层 创建一个用于接收前端请求并调用服务层的方法: ```java @RestController @RequestMapping("/api") public class PhoneController { private final PhoneService phoneService; public PhoneController(PhoneService phoneService) { this.phoneService = phoneService; } @PostMapping("/decryptPhone") public ResponseEntity<Map<String, Object>> decryptPhone(@RequestBody Map<String, String> request) throws Exception { String encryptedData = request.get("encryptedData"); String iv = request.get("iv"); Map<String, Object> result = phoneService.decryptPhone(encryptedData, iv); return new ResponseEntity<>(result, HttpStatus.OK); } } ``` ##### Service 层 定义业务逻辑的服务类,负责实际的解密操作: ```java @Service public class PhoneService { private static final String APP_ID = "your_app_id"; // 替换为自己的 AppId private static final String SECRET_KEY = "your_secret"; // 替换为自己的 SecretKey /** * 解密手机号 */ public Map<String, Object> decryptPhone(String encryptedData, String iv) throws Exception { Session session = getSession(); // 获取会话信息 WeChatDecryptUtil util = new WeChatDecryptUtil( session.getSessionKey(), encryptedData, iv ); return util.decrypt(); } /** * 获取会话信息(模拟) */ private Session getSession() { // 实际项目中应从 Redis 或数据库读取 sesson_key return new Session("example_session_key"); } } class Session { private String sessionKey; public Session(String sessionKey) { this.sessionKey = sessionKey; } public String getSessionKey() { return sessionKey; } } ``` ##### 工具类 (WeChatDecryptUtil) 编写工具类来处理具体的 AES 解密过程: ```java import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.util.Base64; public class WeChatDecryptUtil { private final String sessionKey; private final String encryptedData; private final String iv; public WeChatDecryptUtil(String sessionKey, String encryptedData, String iv) { this.sessionKey = sessionKey; this.encryptedData = encryptedData; this.iv = iv; } public Map<String, Object> decrypt() throws Exception { byte[] decodedSessionKey = Base64.getUrlDecoder().decode(sessionKey); byte[] decodedEncryptedData = Base64.getUrlDecoder().decode(encryptedData); byte[] decodedIv = Base64.getUrlDecoder().decode(iv); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); SecretKeySpec keySpec = new SecretKeySpec(decodedSessionKey, "AES"); IvParameterSpec ivSpec = new IvParameterSpec(decodedIv); cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); byte[] decryptedBytes = cipher.doFinal(decodedEncryptedData); String decryptedString = new String(decryptedBytes, StandardCharsets.UTF_8); ObjectMapper objectMapper = new ObjectMapper(); return objectMapper.readValue(decryptedString, Map.class); // 返回 JSON 数据 } } ``` 以上代码展示了如何通过 Spring Boot 对来自前端的加密数据进行解密,并提取其中的手机号等敏感信息[^1]。 --- #### 注意事项 - 需要确保 `session_key` 是有效的,并且与当前用户的登录状态一致。 - 如果使用的是正式环境,则需注意微信平台对于手机号验证次数的限制。 - 所有的通信建议采用 HTTPS 协议以保障安全性。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值