真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

微信小程序后端開發(fā)的示例分析

這篇文章主要介紹了微信小程序后端開發(fā)的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

創(chuàng)新互聯(lián)公司專注于銅官網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供銅官營銷型網(wǎng)站建設(shè),銅官網(wǎng)站制作、銅官網(wǎng)頁設(shè)計、銅官網(wǎng)站官網(wǎng)定制、微信平臺小程序開發(fā)服務(wù),打造銅官網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供銅官網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。

微信小程序后端開發(fā)流程根據(jù)官網(wǎng)總結(jié)為兩個步驟

1、前端調(diào)用 wx.login 返回了code,然后調(diào)用wx.getUserInfo獲取到用戶的昵稱 頭像

 2、服務(wù)端根據(jù)code去微信獲取openid, 接口地址: https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html%EF%BC%9B%E5%90%8C%E6%97%B6%EF%BC%8C%E6%9B%B4%E6%96%B0%E7%94%A8%E6%88%B7%E6%98%B5%E7%A7%B0%E5%A4%B4%E5%83%8F%E7%AD%89%E8%B5%84%E6%96%99

微信小程序后端接口開發(fā)

controller層

public class OauthController {

  @Autowired
  private WeChatService weChatService;

  /**
   * 微信授權(quán)用js_code換取openId
   * @param code
   * @return
   */
  @GetMapping("/code2Session")
  public BaseResponse code2Session(String code) {
    log.info("code2Session,code={}", code);
    if (StringUtil.isEmpty(code)) {
      return BaseResponse.buildFail("參數(shù)異常");
    }
    Code2SessionResponse res = weChatService.code2Session(code);
    log.info("code2Session,res={}", res);
    if (!res.isSuccess()) {
      return BaseResponse.buildFail(res.getErrCode(), res.getErrMsg());
    }
    return BaseResponse.buildSuccess(res);
  }


 /**
   * 解密獲取手機(jī)號
   * @param request
   * @param response
   * @param param
   * @return
   */
  public BaseResponse decryptGetPhone(HttpServletRequest request, HttpServletResponse response,
                  @RequestBody OauthParam param) {
  
      if (!StringUtil.isEmpty(param.getOpenId())) {//微信授權(quán)登錄
        String sessionKey = weChatService.getSessionKey(param.getOpenId());
        if (StringUtil.isEmpty(sessionKey)) {
          return BaseResponse.buildFail("會話不存在");
        }
        Sha1Utils sha = new Sha1Utils();
        // 獲取用戶信息
        log.debug("微信登陸 sessionKey = {}", sessionKey);
        String userInfoStr = sha.decryptWXAppletInfo(sessionKey, param.getEncryptedData(), param.getIv());
        if (StringUtil.isEmpty(userInfoStr)) {
          return BaseResponse.buildFail("無法獲取用戶信息");
        }
        JSONObject json = JSONObject.parseObject(userInfoStr);
        //綁定微信的手機(jī)號
        String tel = json.getString("purePhoneNumber");
        Assert.isTrue(!StringUtils.isEmpty(tel), "無法獲取用戶手機(jī)號");
        BaseResponse baseResponse=new BaseResponse();
        baseResponse.setResultInfo(tel);
        baseResponse.setState(0);
        return baseResponse;
      }

  }
}

接口

public interface WeChatService {


  /**
   * 用code換取openid
   *
   * @param code
   * @return
   */
  Code2SessionResponse code2Session(String code);


  /**
   * 獲取憑證
   *
   * @return
   */
  String getAccessToken();


  /**
   * 獲取憑證
   *
   * @param isForce
   * @return
   */
  String getAccessToken(boolean isForce);


  String getSessionKey(String openId);

}

實(shí)現(xiàn)類

public class WeChatServiceImpl implements WeChatService {

  //獲取配置文件數(shù)據(jù)
  @Value("${wechat.miniprogram.id}")
  private String appId;

  @Value("${wechat.miniprogram.secret}")
  private String appSecret;

  @Reference
  private SysUserService sysUserService;


  @Override
  public Code2SessionResponse code2Session(String code) {
    String rawResponse = HttpClientUtil
        .get(String.format(WechatConstant.URL_CODE2SESSION, appId, appSecret, code));
    log.info("rawResponse====={}", rawResponse);
    Code2SessionResponse response = JSON.parseObject(rawResponse, Code2SessionResponse.class);
    if (response.isSuccess()) {
      cacheSessionKey(response);
    }
    return response;
  }

  private void cacheSessionKey(Code2SessionResponse response) {
    redisCache redisCache = RedisCache.getInstance();
    String key = RedisCacheKeys.getWxSessionKeyKey(response.getOpenId());
    redisCache.setCache(key, 2147483647, response.getSessionKey());
  }

  @Override
  public String getAccessToken() {
    return getAccessToken(false);
  }

  @Override
  public String getAccessToken(boolean isForce) {
    RedisCache redisCache = RedisCache.getInstance();
    String accessToken = null;
    if (!isForce) {
      accessToken = redisCache.getCache(RedisCacheKeys.getWxAccessTokenKey(appId));
    }
    if (StringUtil.isNotEmpty(accessToken)) {
      return accessToken;
    }
    String rawResponse = HttpClientUtil
        .get(String.format(WechatConstant.URL_GET_ACCESS_TOKEN, appId, appSecret));
    AccessTokenResponse response = JSON.parseObject(rawResponse, AccessTokenResponse.class);
    log.info("getAccessToken:response={}", response);
    if (response.isSuccess()) {
      redisCache.setCache(RedisCacheKeys.getWxAccessTokenKey(appId), 7000, response.getAcessToken());
      return response.getAcessToken();
    }
    return null;
  }


  @Override
  public String getSessionKey(String openId) {
    RedisCache redisCache = RedisCache.getInstance();
    String key = RedisCacheKeys.getWxSessionKeyKey(openId);
    String sessionKey = redisCache.getCache(key);
    return sessionKey;
  }
}

用到的解密工具類

public class Sha1Utils {
  public static String decryptWXAppletInfo(String sessionKey, String encryptedData, String iv) {
    String result = null;
    try {
      byte[] encrypData = Base64.decodeBase64(encryptedData);
      byte[] ivData = Base64.decodeBase64(iv);
      byte[] sessionKeyB = Base64.decodeBase64(sessionKey);

      AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivData);
      Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
      SecretKeySpec keySpec = new SecretKeySpec(sessionKeyB, "AES");
      cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
      byte[] doFinal = cipher.doFinal(encrypData);
      result = new String(doFinal);
      return result;
    } catch (Exception e) {
      //e.printStackTrace();
      log.error("decryptWXAppletInfo error",e);
    }
    return null;
  }

}

網(wǎng)絡(luò)請求工具類

public class HttpClientUtil {

  // utf-8字符編碼
  public static final String            CHARSET_UTF_8     = "utf-8";

  // HTTP內(nèi)容類型。
  public static final String            CONTENT_TYPE_TEXT_HTML = "text/xml";

  // HTTP內(nèi)容類型。相當(dāng)于form表單的形式,提交數(shù)據(jù)
  public static final String            CONTENT_TYPE_FORM_URL = "application/x-www-form-urlencoded";

  // HTTP內(nèi)容類型。相當(dāng)于form表單的形式,提交數(shù)據(jù)
  public static final String            CONTENT_TYPE_JSON_URL = "application/json;charset=utf-8";

  // 連接管理器
  private static PoolingHttpClientConnectionManager pool;

  // 請求配置
  private static volatile RequestConfig requestConfig;

  private static CloseableHttpClient getNewHttpClient() {

    CloseableHttpClient httpClient = HttpClients.custom()
      // 設(shè)置連接池管理
      .setConnectionManager(pool)
      // 設(shè)置請求配置
      .setDefaultRequestConfig(getRequestConfig())
      // 設(shè)置重試次數(shù)
      .setRetryHandler(new DefaultHttpRequestRetryHandler(0, false)).build();

    return httpClient;
  }

  /**
   * 發(fā)送 post請求
   *
   * @param httpUrl
   *      地址
   */
  public static String post(String httpUrl) {
    // 創(chuàng)建httpPost
    HttpPost httpPost = new HttpPost(httpUrl);
    return request(httpPost);
  }

  public static byte[] postRaw(String httpUrl) {
    // 創(chuàng)建httpPost
    HttpPost httpPost = new HttpPost(httpUrl);
    return requestRaw(httpPost);
  }

  /**
   * 發(fā)送 get請求
   *
   * @param httpUrl
   */
  public static String get(String httpUrl) {
    // 創(chuàng)建get請求
    HttpGet httpGet = new HttpGet(httpUrl);
    return request(httpGet);
  }

  /**
   * 發(fā)送 post請求(帶文件)
   *
   * @param httpUrl
   *      地址
   * @param maps
   *      參數(shù)
   * @param fileLists
   *      附件
   */
  public static String post(String httpUrl, Map maps, List fileLists,
               String fileName) {
    HttpPost httpPost = new HttpPost(httpUrl);// 創(chuàng)建httpPost
    MultipartEntityBuilder meBuilder = MultipartEntityBuilder.create();
    if (maps != null) {
      for (String key : maps.keySet()) {
        meBuilder.addPart(key, new StringBody(maps.get(key), ContentType.TEXT_PLAIN));
      }
    }
    if (fileLists != null) {
      for (File file : fileLists) {
        FileBody fileBody = new FileBody(file);
        meBuilder.addPart(fileName, fileBody);
      }
    }
    HttpEntity reqEntity = meBuilder.build();
    httpPost.setEntity(reqEntity);
    return request(httpPost);
  }

  public static String post(String httpUrl, Map maps, List fileLists) {
    return post(httpUrl, maps, fileLists, "file");
  }

  public static String post(String httpUrl, List fileLists) {
    return post(httpUrl, Collections.emptyMap(), fileLists, "file");
  }

  /**
   * 發(fā)送 post請求
   *
   * @param httpUrl
   *      地址
   * @param params
   *      參數(shù)(格式:key1=value1&key2=value2)
   *
   */
  public static String post(String httpUrl, String params) {
    HttpPost httpPost = new HttpPost(httpUrl);// 創(chuàng)建httpPost
    try {
      // 設(shè)置參數(shù)
      if (params != null && params.trim().length() > 0) {
        StringEntity stringEntity = new StringEntity(params, "UTF-8");
        stringEntity.setContentType(CONTENT_TYPE_FORM_URL);
        httpPost.setEntity(stringEntity);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return request(httpPost);
  }

  /**
   * 發(fā)送 post請求
   *
   * @param maps
   *      參數(shù)
   */
  public static String post(String httpUrl, Map maps) {
    String param = convertStringParamter(maps);
    return post(httpUrl, param);
  }



  /**
   * 發(fā)送 post請求 發(fā)送json數(shù)據(jù)
   *
   * @param httpUrl
   *      地址
   * @param content
   *
   *
   */
  public static String post(String httpUrl, String content, String contentType) {
    //    HttpPost httpPost = new HttpPost(httpUrl);// 創(chuàng)建httpPost
    //    try {
    //      // 設(shè)置參數(shù)
    //      if (StringUtils.isNotEmpty(content)) {
    //        StringEntity stringEntity = new StringEntity(content, "UTF-8");
    //        stringEntity.setContentType(contentType);
    //        httpPost.setEntity(stringEntity);
    //      }
    //    } catch (Exception e) {
    //      e.printStackTrace();
    //    }
    //    return request(httpPost);
    return new String(postRaw(httpUrl, content, contentType), StandardCharsets.UTF_8);
  }

  public static byte[] postRaw(String httpUrl, String content, String contentType) {
    HttpPost httpPost = new HttpPost(httpUrl);// 創(chuàng)建httpPost
    try {
      // 設(shè)置參數(shù)
      if (StringUtils.isNotEmpty(content)) {
        StringEntity stringEntity = new StringEntity(content, "UTF-8");
        stringEntity.setContentType(contentType);
        httpPost.setEntity(stringEntity);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return requestRaw(httpPost);
  }

  /**
   * 發(fā)送 post請求 發(fā)送json數(shù)據(jù)
   *
   * @param httpUrl
   *      地址
   * @param paramsJson
   *      參數(shù)(格式 json)
   *
   */
  public static String postJson(String httpUrl, String paramsJson) {
    return post(httpUrl, paramsJson, CONTENT_TYPE_JSON_URL);
  }

  public static byte[] postJsonRaw(String httpUrl, String paramsJson) {
    return postRaw(httpUrl, paramsJson, CONTENT_TYPE_JSON_URL);
  }

  /**
   * 發(fā)送 post請求 發(fā)送xml數(shù)據(jù)
   *
   * @param url  地址
   * @param paramsXml 參數(shù)(格式 Xml)
   *
   */
  public static String postXml(String url, String paramsXml) {
    return post(url, paramsXml, CONTENT_TYPE_TEXT_HTML);
  }

  /**
   * 將map集合的鍵值對轉(zhuǎn)化成:key1=value1&key2=value2 的形式
   *
   * @param parameterMap
   *      需要轉(zhuǎn)化的鍵值對集合
   * @return 字符串
   */
  public static String convertStringParamter(Map parameterMap) {
    StringBuilder parameterBuffer = new StringBuilder();
    if (parameterMap != null) {
      Iterator iterator = parameterMap.keySet().iterator();
      String key = null;
      String value = null;
      while (iterator.hasNext()) {
        key = (String) iterator.next();
        if (parameterMap.get(key) != null) {
          value = (String) parameterMap.get(key);
        } else {
          value = "";
        }
        parameterBuffer.append(key).append("=").append(value);
        if (iterator.hasNext()) {
          parameterBuffer.append("&");
        }
      }
    }
    return parameterBuffer.toString();
  }

  /**
   * 發(fā)送請求
   *
   * @param request
   * @return
   */
  public static byte[] requestRaw(HttpRequestBase request) {

    CloseableHttpClient httpClient;
    CloseableHttpResponse response = null;
    // 響應(yīng)內(nèi)容
    //    String responseContent = null;
    byte[] rawResponse = null;
    try {
      // 創(chuàng)建默認(rèn)的httpClient實(shí)例.
      httpClient = getNewHttpClient();
      // 配置請求信息
      request.setConfig(requestConfig);
      // 執(zhí)行請求
      response = httpClient.execute(request);
      // 得到響應(yīng)實(shí)例
      HttpEntity entity = response.getEntity();

      // 可以獲得響應(yīng)頭
      // Header[] headers = response.getHeaders(HttpHeaders.CONTENT_TYPE);
      // for (Header header : headers) {
      // System.out.println(header.getName());
      // }

      // 得到響應(yīng)類型
      // System.out.println(ContentType.getOrDefault(response.getEntity()).getMimeType());

      // 判斷響應(yīng)狀態(tài)
      if (response.getStatusLine().getStatusCode() >= 300) {
        throw new Exception("HTTP Request is not success, Response code is "
                  + response.getStatusLine().getStatusCode());
      }

      if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode()) {
        rawResponse = EntityUtils.toByteArray(entity);
        //        responseContent = EntityUtils.toString(entity, CHARSET_UTF_8);
        EntityUtils.consume(entity);
      }

    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        // 釋放資源
        if (response != null) {
          response.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return rawResponse;
  }

  private static String request(HttpRequestBase req) {
    return new String(requestRaw(req), StandardCharsets.UTF_8);
  }

  private static RequestConfig getRequestConfig() {

    if (requestConfig == null) {
      synchronized (HttpClientUtil.class) {
        if (requestConfig == null) {
          try {
            //System.out.println("初始化HttpClientTest~~~開始");
            SSLContextBuilder builder = new SSLContextBuilder();
            builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
              builder.build());
            // 配置同時支持 HTTP 和 HTPPS
            Registry socketFactoryRegistry = RegistryBuilder
              . create()
              .register("http", PlainConnectionSocketFactory.getSocketFactory())
              .register("https", sslsf).build();
            // 初始化連接管理器
            pool = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
            // 將最大連接數(shù)增加到200,實(shí)際項目最好從配置文件中讀取這個值
            pool.setMaxTotal(200);
            // 設(shè)置最大路由
            pool.setDefaultMaxPerRoute(2);
            // 根據(jù)默認(rèn)超時限制初始化requestConfig
            int socketTimeout = 10000;
            int connectTimeout = 10000;
            int connectionRequestTimeout = 10000;
            requestConfig = RequestConfig.custom()
              .setConnectionRequestTimeout(connectionRequestTimeout)
              .setSocketTimeout(socketTimeout).setConnectTimeout(connectTimeout)
              .build();

          } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
          } catch (KeyStoreException e) {
            e.printStackTrace();
          } catch (KeyManagementException e) {
            e.printStackTrace();
          }

          // 設(shè)置請求超時時間
          requestConfig = RequestConfig.custom().setSocketTimeout(50000)
            .setConnectTimeout(50000).setConnectionRequestTimeout(50000).build();
        }
      }
    }
    return requestConfig;
  }
}

常量

public interface WechatConstant {
  Integer OK_STATUS      = 0;
  String URL_CODE2SESSION   = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code";


  String URL_GET_ACCESS_TOKEN   = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";


  String URL_GET_IMAGE = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=%s&media_id=%s";
  
  
  /**
   * 給公眾號發(fā)送信息。參考https://mp.weixin.qq.com/advanced/tmplmsg?action=faq&token=708366329&lang=zh_CN
   */
  String URL_SEND_TO_CHANNEL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s";
  String URL_SEND_MESSAGE   = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s";
  
  /**
   * 發(fā)送模板消息。參考https://developers.weixin.qq.com/miniprogram/dev/api-backend/sendMiniTemplateMessage.html
   */
  String URL_SEND_TEMPLATE_MESSAGE = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=%s";

  String URL_QR_CODE_UNLIMTED = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s";
  
  String URL_QR_CODE = "https://api.weixin.qq.com/wxa/getwxacode?access_token=%s";

  /**
   * 獲取標(biāo)簽下粉絲列表
   */
  String URL_ALL_FANS_OPENID = "https://api.weixin.qq.com/cgi-bin/user/tag/get?access_token=%s";
  /**
   * 獲取公眾號已創(chuàng)建的標(biāo)簽
   */
  String URL_ALL_TAGS = "https://api.weixin.qq.com/cgi-bin/tags/get?access_token=%s";

}

使用到的實(shí)體類

public class Code2SessionResponse implements Serializable {
  public static Integer RESPONSE_OK = 0;

  @JSONField(name = "openid")
  private String    openId;
  @JSONField(name = "session_key")
  private String    sessionKey;
  @JSONField(name = "unionid")
  private String    unionId;
  @JSONField(name = "errcode")
  private Integer   errCode;
  @JSONField(name = "errmsg")
  private String   errMsg;



  public boolean isSuccess() {
    return this.errCode == null || RESPONSE_OK.equals(this.errCode);
  }
}

總結(jié):微信小程序的后端開發(fā)主要就是對用戶進(jìn)行授權(quán) , 1、前端調(diào)用 wx.login 返回了code,然后調(diào)用wx.getUserInfo獲取到用戶的昵稱 頭像 2.首先通過微信授權(quán)用js_code換取openId,來獲取openId,前端傳微信的參數(shù) code字段 3.然后解密獲取手機(jī)號 前端需要傳openId encryptedData iv 等字段來獲取用戶的的授權(quán)手機(jī)號

這些信息都獲取后 接著就是調(diào)用后端的登陸接口,登陸接口如果只有授權(quán)登錄就是我們將接口參數(shù)為下圖最后三個字段為前端必填字段

微信小程序后端開發(fā)的示例分析 

主要步驟是根據(jù)前端的openId獲取sessionKey 然后根據(jù)sessionKey 和其他參數(shù)進(jìn)行解密獲取用戶手機(jī)號

通過解密獲取授權(quán)登錄的手機(jī)號,然后根據(jù)自己的業(yè)務(wù)邏輯處理即可,這樣我們就可以根據(jù)授權(quán)的手機(jī)號進(jìn)行授權(quán)登錄

微信小程序后端開發(fā)的示例分析

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“微信小程序后端開發(fā)的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識等著你來學(xué)習(xí)!


文章名稱:微信小程序后端開發(fā)的示例分析
URL網(wǎng)址:http://weahome.cn/article/ghcejp.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部