1. 首页
  2. 小程序开发
  3. 正文

java开发微信小程序功能

  小程序登录

  整体流程如下:

  - 1.获取code

  - 2.用步骤1获取到的临时code换取用户唯一标识OpenId和会话密钥 session_key

  - 3.获取用户手机号,用进行登录

  请求地址:GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code

  请求参数:

  请求参数:


返回值:


  开发前准备(必须)

      appid:wx4c1d53****7a671

      appsecret:fc9f99c08dcb2a0****eb26376c65eae

     小程序代码:

login.js

    // pages/login/login.wxml.jsconst app = getApp();Page({
    /** * 页面的初始数据 */ data: { // 判断小程序的API,回调,参数,组件等是否在当前版本可用。 canIUse: wx.canIUse('button.open-type.getPhoneNumber'), wechat: '微信快捷登录', isShow: false },
    /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { // 从缓存中取手机号 console.log("获取手机号!") try { var value = wx.getStorageSync('phoneNumber') if (value) { // 说明已登录 跳转 页面 console.log("获取缓存:"+value) wx.navigateTo({ url: '../login?param=' + value }) }else{// 未登录 显示 微信授权页面 this.setData({ isShow: true }) } } catch (e) {
    } // 解决第一次获取手机号失败问题 wx.login({ success: res => { if(res.code){ console.log("code->", res.code) } } }) },
    // 0.获取手机号授权 getPhoneNumber: function(e) { // 用户拒绝授权 if(e.detail.errMsg == "getPhoneNumber:fail user deny") { wx.showToast({ icon: "none", title: '请允许获取手机号,否则功能不可用!', }) return } // console.log("e->detail", e.detail) /// 用户允许授权 // console.log("iv->", e.detail.iv); //包括敏感数据在内的完整用户信息的加密数据,需要解密 // console.log("encryptedData->", e.detail.encryptedData); //加密算法的初始向量,解密需要用到
    /// 获取手机号 // 1.获取临时登录凭证code wx.login({ success: res => { if(res.code){ this.code = res.code; console.log("code->", res.code) console.log("encryptedData->", encodeURIComponent(e.detail.encryptedData)) console.log("iv->", e.detail.iv) this.getSessionKey(res.code, e.detail.encryptedData, e.detail.iv); } } }) }, // 2.访问登录凭证校验接口获取session_key(后续改成后台实现) getSessionKey: function(js_code, encryptedData, iv) { // 3. 解密获取手机号 wx.request({ url: 'http://localhost:8082/wechat/appletLogin', data: { 'encryptedData': encodeURIComponent(encryptedData),//需要进行编码 'iv': iv, 'jscode': js_code }, method: 'POST', header: { 'content-type': 'application/json' }, // 设置请求的 header success: function(data2) { var data = data2.data console.log(data) if(data.resultCode == 200) { if(data.data.user.phone==undefined){ // 获取手机号失败 跳转到 常规 用户登录页面(通过webview) wx.navigateTo({ url: '用户登录页' }) return } // 存储数据到缓存 wx.setStorage({ key:"phoneNumber", data:data.data.user.phone }) // 4.跳转页面 } }, fail: function(err) { console.log(err); wx.showToast({ icon: "none", title: '获取手机号失败,请重试!', }) } }) },
    /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () {
    },
    /** * 生命周期函数--监听页面显示 */ onShow: function () {
    },
    /** * 生命周期函数--监听页面隐藏 */ onHide: function () {
    },
    /** * 生命周期函数--监听页面卸载 */ onUnload: function () {
    },
    /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () {
    },
    /** * 页面上拉触底事件的处理函数 */ onReachBottom: function () {
    },
    /** * 用户点击右上角分享 */ onShareAppMessage: function () {
    }})

    login.json

      {  "usingComponents": {}}

      login.wxml

        <!--pages/login.wxml--><view class="modal-mask" catchtouchmove="preventTouchMove" wx:if="{{isShow}}"></view>  <view class="modal-dialog" wx:if="{{isShow}}">  <view class="modal-content">    <view><image src='../images/show.png' class='show'></image></view>    <!-- <view>绑定手机号</view>    <view>请先绑定手机号在进行此操作</view>   -->    <button class="show" type="primary" lang="zh_CN"    open-type='getPhoneNumber' bindgetphonenumber="getPhoneNumber" >      微信用户一键登录    </button>  </view></view>

        login.wxss

          /* pages/login/login.wxml.wxss */.show{  display: block;  border-radius: 8rpx;  margin: 20rpx 20rpx 20rpx 20rpx;  font-size: 35rpx;}
          .container{ position: fixed; /*关键属性,设置为fixed*/ display: flex; flex-direction: column; width: 100%; height: 100%;}

          后端代码

          WxLoginController.java

            @RestController@RequestMapping("/wechat")public class WxLoginController {
            private Logger logger = LoggerFactory.getLogger(WxLoginController.class); @Autowired UserDao userDao; @Value("${wechat.appid}") private String appid; @Value("${wechat.appsecret}") private String appsecret; private Map<String, Object> userMap = new HashMap<>(); @GetMapping("/appletLogin") public ResultBean appletLogin(String encryptedData, String iv, String jscode) { System.out.println(encryptedData); ResultBean resultBean = new ResultBean(); // jscode if (StringUtils.isEmpty(jscode)) { resultBean.setResultCode(-10001); resultBean.setResultMessage("鉴权失败!"); return resultBean; } // sign if (StringUtils.isEmpty(encryptedData)) { resultBean.setResultCode(-10001); resultBean.setResultMessage("鉴权失败!"); return resultBean; } if(StringUtils.isBlank(iv)) { resultBean.setResultCode(-10002); resultBean.setResultMessage("鉴权失败!"); return resultBean; }
            // 创建Httpclient对象 CloseableHttpClient httpclient = HttpClients.createDefault(); String resultString = ""; CloseableHttpResponse response = null; String url =WxContants.url.replace(WxContants.APPID, appid). replace(WxContants.SECRET, appsecret).replace(WxContants.JSCODE, jscode);
            try { // 创建uri URIBuilder builder = new URIBuilder(url); URI uri = builder.build();
            // 创建http GET请求 HttpGet httpGet = new HttpGet(uri);
            // 执行请求 response = httpclient.execute(httpGet); // 判断返回状态是否为200 if (response.getStatusLine().getStatusCode() == 200) { resultString = EntityUtils.toString(response.getEntity(), "UTF-8"); } } catch (Exception e) { e.printStackTrace(); }
            // 解析json JSONObject jsonObject = (JSONObject) JSONObject.parse(resultString); String session_key = jsonObject.getString("session_key"); String openid = jsonObject.getString("openid");
            System.out.println("session_key:"+session_key + ",openid:"+openid); if (StringUtils.isEmpty(session_key)) { resultBean.setResultCode(-10003); resultBean.setResultMessage("获取sessionkey失败!"); return resultBean; }
            // 解码 try { encryptedData = URLDecoder.decode(encryptedData,"UTF-8"); } catch (UnsupportedEncodingException e) { logger.error("encryptedData,decode失败!", e); resultBean.setResultCode(-10003); resultBean.setResultMessage("encryptedData,decode失败!"); return resultBean; } String decryptData = WechatDecryptDataUtil.decryptData(encryptedData, session_key, iv); JSONObject userInfo = JSONObject.parseObject(decryptData); // 存入redis+数据库,判断是否存在redis中,存在直接从redis返回 // 本地使用Map模拟 if (!userMap.containsKey(openid)) { // 判断用户是否存在系统中 String phoneNumber = userInfo.getString("phoneNumber"); User user = userDao.findByPhone(phoneNumber); if (user == null) { resultBean.setResultCode(200); resultBean.setResultMessage("此用户不存在,请先注册!"); return resultBean; } user.setOpenId(openid); userDao.save(user); userMap.put(openid, user); } User user = (User) userMap.get(openid); resultBean.setResultCode(200); resultBean.setResultMessage("成功!"); resultBean.setData(user); return resultBean; }}

            UserDao.java

            public interface UserDao extends JpaRepository<User, Long> {
            User findByPhone(String phone);
            User findByOpenId(String openId);}

            User.java:

            @Entity@Table(name = "user")public class User {
            @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String openId; private String phone;
            public Long getId() { return id; }
            public void setId(Long id) { this.id = id; }
            public String getOpenId() { return openId; }
            public void setOpenId(String openId) { this.openId = openId; }
            public String getPhone() { return phone; }
            public void setPhone(String phone) { this.phone = phone; }}

            WechatDecryptDataUtil.java

              public class WechatDecryptDataUtil {    private static Logger logger = LogManager.getLogger(WechatDecryptDataUtil.class);
              public static void main(String[] args) { String result = decryptData( "BLY05rL1qLzGdqn+m4s4KfnM9CbMCm2sTZmgIcUJUpoOVeZkKKYh06ATVm2BgX8HUsH1a93811fhwr70MTh2Pk2qw9rPBzvos3husUJdVfaZgBk3Afp6wNFS0/kcoyt+7q2eMrIHMe6wkc4J0hgbbkxdUwZag/pyKXwe4pUzSQfta7dfBHy3DLu+REvwHiDNfvI3KJbZ0l8/9vRjfSmT4Q==", "C9Z59YjFkCDT8+9NQ3OxcA==", "oOWTpbZ80evG/GQqRdUu3w==" ); System.out.println("result = " + result); }
              public synchronized static String decryptData(String encryptDataB64, String sessionKeyB64, String ivB64) { String res = null; try { res = new String( decryptOfDiyIV( Base64.decode(encryptDataB64), Base64.decode(sessionKeyB64), Base64.decode(ivB64) ) ); } catch (Exception e) { logger.error("encryptDataB64:"+encryptDataB64+"\n"+"sessionKeyB64:"+sessionKeyB64+"\n"+"ivB64:"+ivB64); }
              return res; }
              private static final String KEY_ALGORITHM = "AES"; private static final String ALGORITHM_STR = "AES/CBC/PKCS7Padding"; private static Key key; private static Cipher cipher;
              private static void init(byte[] keyBytes) { // 如果密钥不足16位,那么就补足. 这个if 中的内容很重要 int base = 16; if (keyBytes.length % base != 0) { int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0); byte[] temp = new byte[groups * base]; Arrays.fill(temp, (byte) 0); System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length); keyBytes = temp; } // 初始化 Security.addProvider(new BouncyCastleProvider()); // 转化成JAVA的密钥格式 key = new SecretKeySpec(keyBytes, KEY_ALGORITHM); try { // 初始化cipher cipher = Cipher.getInstance(ALGORITHM_STR, "BC"); } catch (Exception e) { e.printStackTrace(); } }
              /** * 解密方法 * * @param encryptedData 要解密的字符串 * @param keyBytes 解密密钥 * @param ivs 自定义对称解密算法初始向量 iv * @return 解密后的字节数组 */ private static byte[] decryptOfDiyIV(byte[] encryptedData, byte[] keyBytes, byte[] ivs) { byte[] encryptedText = null; init(keyBytes); try { cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(ivs)); encryptedText = cipher.doFinal(encryptedData); } catch (Exception e) { e.printStackTrace(); } return encryptedText; }
              }

              WxContants.java

                public interface WxContants {
                String APPID = "APPID"; String SECRET = "SECRET"; String JSCODE = "JSCODE"; String TRADE_TYPE = "JSAPI"; String url = "https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code";}

                  延伸阅读

                • 简单的Java小程序

                  (一)简单的java程序publicclassMyFirstApp{publicstaticvoidmain(String[]args){System.out.print(He...

                本文来自投稿,不代表本人立场,如若转载,请注明出处:http://lnbdc.com/article/7214.html

                (function(){ var src = (document.location.protocol == "http:") ? "http://js.passport.qihucdn.com/11.0.1.js?1d7dde81dc0903e04d3ac0b9599444f6":"https://jspassport.ssl.qhimg.com/11.0.1.js?1d7dde81dc0903e04d3ac0b9599444f6"; document.write('<\/mip-script>'); })(); (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();