[小程式開發實戰]使用WxJava實現手機號獲取

kudoForever發表於2022-11-06

之前編寫小程式獲取手機號相關的程式碼均為自行封裝,最近發現了 WxJava 的存在,方便了開發。

本篇文章將講解如何使用WxJava進行手機號的獲取。
舊版本微信介面官方文件

思路

需要將 button 元件 open-type 的值設定為 getPhoneNumber,當使用者點選並同意之後,可以透過 bindgetphonenumber 事件回撥獲取到微信伺服器返回的加密資料, 然後在第三方服務端結合 session_key 以及 app_id 進行解密獲取手機號。

總結為以下兩個步驟:

  1. 透過使用 button getPhoneNumber 可獲取到 返回的加密資料。
  2. 然後將加密資料結合 session_key 以及 app_id 進行解密獲取手機號。

因此想要獲得使用者的手機號,我們需要傳入 session_key, app_id 以及 前端呼叫微信伺服器返回的加密資料。

  • 如何獲取 session_key 和 app_id 呢?
    前端獲取jsCode後並呼叫 auth.code2Session 介面即可。

因此我們只需要將 jsCode 以及 加密資料 傳給介面即可。

整體思路總結

  1. 前端給後端傳遞 jsCode,加密資料引數(iv,encryptedData)。
  2. 然後使用 jsCode,繫結的 appId 以及 appSecret 呼叫 auth.code2Session 介面 獲取到 session_key,app_id 。
  3. 使用 session_key,app_id 對加密資料進行解密獲取到使用者手機號。

程式碼實現

這裡使用了 wxjava。因此程式碼非常的簡潔。我們只需要理解整體的思路就好了。

整體架構

【小程式開發實戰】使用WxJava實現手機號獲取

wxMaConfigration



/**  
 * @author <a href="https://github.com/binarywang">Binary Wang</a>  
 */@Slf4j  
@Configuration  
@EnableConfigurationProperties(WxMaProperties.class)  
public class WxMaConfiguration {  
    private final WxMaProperties properties;  

    @Autowired  
    public WxMaConfiguration(WxMaProperties properties) {  
        this.properties = properties;  
    }  

    @Bean  
    public WxMaService wxMaService() {  
        List<WxMaProperties.Config> configs = this.properties.getConfigs();  
        if (configs == null) {  
            throw new WxRuntimeException("大哥,拜託先看下專案首頁的說明(readme檔案),新增下相關配置,注意別配錯了!");  
        }  
        WxMaService maService = new WxMaServiceImpl();  
        maService.setMultiConfigs(  
            configs.stream()  
                .map(a -> {  
                    WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();  
//                WxMaDefaultConfigImpl config = new WxMaRedisConfigImpl(new JedisPool());  
                    // 使用上面的配置時,需要同時引入jedis-lock的依賴,否則會報類無法找到的異常  
                    config.setAppid(a.getAppid());  
                    config.setSecret(a.getSecret());  
                    config.setToken(a.getToken());  
                    config.setAesKey(a.getAesKey());  
                    config.setMsgDataFormat(a.getMsgDataFormat());  
                    return config;  
                }).collect(Collectors.toMap(WxMaDefaultConfigImpl::getAppid, a -> a, (o, n) -> o)));  
        return maService;  
    }  

    @Bean  
    public WxMaMessageRouter wxMaMessageRouter(WxMaService wxMaService) {  
        final WxMaMessageRouter router = new WxMaMessageRouter(wxMaService);  
        router  
            .rule().handler(logHandler).next()  
            .rule().async(false).content("訂閱訊息").handler(subscribeMsgHandler).end()  
            .rule().async(false).content("文字").handler(textHandler).end()  
            .rule().async(false).content("圖片").handler(picHandler).end()  
            .rule().async(false).content("二維碼").handler(qrcodeHandler).end();  
        return router;  
    }  

    private final WxMaMessageHandler subscribeMsgHandler = (wxMessage, context, service, sessionManager) -> {  
        service.getMsgService().sendSubscribeMsg(WxMaSubscribeMessage.builder()  
            .templateId("此處更換為自己的模板id")  
            .data(Lists.newArrayList(  
                new WxMaSubscribeMessage.MsgData("keyword1", "339208499")))  
            .toUser(wxMessage.getFromUser())  
            .build());  
        return null;  
    };  

    private final WxMaMessageHandler logHandler = (wxMessage, context, service, sessionManager) -> {  
        log.info("收到訊息:" + wxMessage.toString());  
        service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("收到資訊為:" + wxMessage.toJson())  
            .toUser(wxMessage.getFromUser()).build());  
        return null;  
    };  

    private final WxMaMessageHandler textHandler = (wxMessage, context, service, sessionManager) -> {  
        service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("回覆文字訊息")  
            .toUser(wxMessage.getFromUser()).build());  
        return null;  
    };  

    private final WxMaMessageHandler picHandler = (wxMessage, context, service, sessionManager) -> {  
        try {  
            WxMediaUploadResult uploadResult = service.getMediaService()  
                .uploadMedia("image", "png",  
                    ClassLoader.getSystemResourceAsStream("tmp.png"));  
            service.getMsgService().sendKefuMsg(  
                WxMaKefuMessage  
                    .newImageBuilder()  
                    .mediaId(uploadResult.getMediaId())  
                    .toUser(wxMessage.getFromUser())  
                    .build());  
        } catch (WxErrorException e) {  
            e.printStackTrace();  
        }  

        return null;  
    };  

    private final WxMaMessageHandler qrcodeHandler = (wxMessage, context, service, sessionManager) -> {  
        try {  
            final File file = service.getQrcodeService().createQrcode("123", 430);  
            WxMediaUploadResult uploadResult = service.getMediaService().uploadMedia("image", file);  
            service.getMsgService().sendKefuMsg(  
                WxMaKefuMessage  
                    .newImageBuilder()  
                    .mediaId(uploadResult.getMediaId())  
                    .toUser(wxMessage.getFromUser())  
                    .build());  
        } catch (WxErrorException e) {  
            e.printStackTrace();  
        }  

        return null;  
    };  

}

wxMaProperties

@Data  
@ConfigurationProperties(prefix = "wx.miniapp")  
public class WxMaProperties {  

    private List<Config> configs;  

    @Data  
    public static class Config {  
        /**  
         * 設定微信小程式的appid  
         */        private String appid;  

        /**  
         * 設定微信小程式的Secret  
         */        private String secret;  

        /**  
         * 設定微信小程式訊息伺服器配置的token  
         */        private String token;  

        /**  
         * 設定微信小程式訊息伺服器配置的EncodingAESKey  
         */        private String aesKey;  

        /**  
         * 訊息格式,XML或者JSON  
         */        private String msgDataFormat;  
    }  

}

wxcontroller

@RestController  
@RequestMapping("/wx")  
@AllArgsConstructor  
public class WxController {  

    private final WxMaService wxMaService;  


    @PostMapping("/decrypt")  
    public JSONObject decrypt(@RequestBody AuthDto authDto) throws WxErrorException {  
        WxMaJscode2SessionResult wxMaJscode2SessionResult  = new WxMaJscode2SessionResult();  
        try{  
         wxMaJscode2SessionResult =  wxMaService.jsCode2SessionInfo(authDto.getJsCode());  
        }  
        catch (Exception e){  
            throw e;  
        }  


        WxMaPhoneNumberInfo phoneNumberInfo = wxMaService.getUserService().getPhoneNoInfo(wxMaJscode2SessionResult.getSessionKey(),authDto.getEncryptedData(), authDto.getIv());  
        JSONObject result = new JSONObject();  
        HashMap<String,Object> resultMap = new HashMap<>();  
        resultMap.put("data",phoneNumberInfo);  
        result.put("result",resultMap);  
        return result;  
    }  


}

application.yml

wx:  
  miniapp:  
    configs:  
          appid: '自己的小程式appid'  
          secret: 'appsecret'  
          token: #微信小程式訊息伺服器配置的token  
          aesKey: #微信小程式訊息伺服器配置的EncodingAESKey  
          msgDataFormat: JSON
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章