亚洲国产精品无码久久大片,亚洲AV无码乱码麻豆精品国产,亚洲品质自拍网站,少妇伦子伦精品无码STYLES,国产精久久久久久久

開(kāi)發(fā)接入2.1微信公眾平臺接口測試賬號的申請流程及步驟

優(yōu)采云 發(fā)布時(shí)間: 2021-08-01 00:31

  開(kāi)發(fā)接入2.1微信公眾平臺接口測試賬號的申請流程及步驟

  一、前言

  隨著(zhù)微信的普及,年輕一代逐漸從QQ轉向微信。界面簡(jiǎn)潔,功能強大,男女老少皆宜,是微信的特色。正是這一特性,使微信成為了中國社交軟件的巨頭。因此,很多產(chǎn)品需要在微信中開(kāi)發(fā)以滿(mǎn)足需求。

  本文主要講服務(wù)號的開(kāi)發(fā),與微信服務(wù)器的交互,以及使用微信公眾號的Oauth2授權,在微信中展示本地開(kāi)發(fā)的內容并進(jìn)行交互。由于公眾號申請需要時(shí)間和經(jīng)驗,需要公司相關(guān)資質(zhì),作為個(gè)人開(kāi)發(fā)者,可以先在微信官方平臺申請測試號,使用測試號授權與微信服務(wù)器交互并調試這一頁(yè)。在開(kāi)始之前,朋友們需要了解他們的需求。微信分為企業(yè)號、服務(wù)號、訂閱號。不同的賬戶(hù)有不同的功能。具體可以到微信官網(wǎng)查看需要開(kāi)發(fā)什么類(lèi)型的賬號。

  

  二、development 接入2.1 微信公眾平臺接口測試賬號申請

  如前言所述,在開(kāi)發(fā)中,我們一半人會(huì )使用官方微信公眾號作為我們的生產(chǎn)線(xiàn)環(huán)境,然后aut環(huán)境可以使用測試號進(jìn)行開(kāi)發(fā),從而實(shí)現與微信的交互。測試賬號申請鏈接如下

  測試帳戶(hù)申請

  進(jìn)入后,您將看到以下屏幕。登錄

  

  登錄后,您會(huì )看到以下屏幕:

  

  因為我已經(jīng)配置好了,所以顯示配置后的相關(guān)參數。如果是第一次進(jìn)入,需要自己配置相關(guān)參數。首先要注意的是,系統會(huì )為你生成一個(gè)appId,appsercet,后面會(huì )講到這個(gè)的作用?,F在你需要配置 URL 和 Token。

  具體來(lái)說(shuō),這個(gè)所謂的URL就是你需要在你的代碼中與微信進(jìn)行Token驗證交互的一種方法。配置完成后,微信會(huì )使用配置的url發(fā)起http請求。請注意,發(fā)起方法是獲取請求。因此,代碼中提供的接口需要將請求頭設置為get請求:

  method=(RequestMethod.GET) 方法中需要驗證微信發(fā)送的消息。下面的token需要和你項目中配置的token一致。微信發(fā)送請求后,會(huì )帶上簽名和時(shí)間戳。 , 隨機數被檢查。如果匹配成功,則可以進(jìn)行下一步。如果不一致,則匹配失敗。需要注意的是,這個(gè)url需要有自己的域名。我個(gè)人在Sunny-Ngrok上申請了內網(wǎng)穿透,并贈送了一個(gè)域名。

  2.2 sunn-Ngrok 內網(wǎng)滲透賬號申請

  點(diǎn)擊申請賬號

  

  賬戶(hù)創(chuàng )建后,會(huì )有如上圖所示。其實(shí),開(kāi)通域名的方式有很多種。這里我只是給我一個(gè)參考方法。然后點(diǎn)擊打開(kāi)隧道,購買(mǎi)隧道

  

  一個(gè)月10元不算貴。購買(mǎi)后點(diǎn)擊隧道管理

  

  購買(mǎi)后會(huì )有記錄,可以同時(shí)查看贈送域名和查看狀態(tài)。此時(shí)的狀態(tài)為離線(xiàn)。如果是離線(xiàn),微信公眾平臺微信發(fā)起的請求無(wú)法配置從本機接受,需要到官網(wǎng)下載客戶(hù)端啟動(dòng)隧道。

  cmd命令行進(jìn)入sunny.exe所在目錄并執行

  sunny.exe clientid 隧道 ID

  

  如上圖所示,將域名指向你本地的ip和端口號后,就可以在公眾號提交配置了。在我自己機器的代碼中,我做了如下配置:

  @RequestMapping(value = "/wx/wxmsgreceive", method = {RequestMethod.GET})

public void verifywxtoken(HttpServletRequest request, HttpServletResponse response) throws Exception {

request.setCharacterEncoding("UTF-8");

response.setCharacterEncoding("UTF-8");

logger.info("開(kāi)始校驗信息是否是從微信服務(wù)器發(fā)出");

// 簽名

String signature = request.getParameter("signature");

// 時(shí)間戳

String timestamp = request.getParameter("timestamp");

// 隨機數

String nonce = request.getParameter("nonce");

// 通過(guò)檢驗signature對請求進(jìn)行校驗,若校驗成功則原樣返回echostr,表示接入成功,否則接入失敗

String result = Sha1.gen(SERVER_TOKEN, timestamp, nonce);

if (signature.equals(result)) {

// 隨機字符串

String echostr = request.getParameter("echostr");

logger.debug("接入成功,echostr {}", echostr);

response.getWriter().write(echostr);

}

}

  微信驗證碼

  public static String gen(String token, String timestamp, String nonce) throws NoSuchAlgorithmException {

String[] arr = new String[]{token, timestamp, nonce};

Arrays.sort(arr);

StringBuffer content = new StringBuffer();

for (String a : arr) {

content.append(a);

}

return DigestUtils.sha1Hex(content.toString());

}

  因為我配置的請求頭是/wx/wxmsgreceive,所以公共平臺上的配置頁(yè)面是域名+/wx/wxmsgreceive。

  此時(shí),當您在網(wǎng)頁(yè)上點(diǎn)擊提交時(shí),微信會(huì )向本機發(fā)送認證請求,以確保本機的服務(wù)必須開(kāi)啟。

  

  這是官方的說(shuō)明,所以我們開(kāi)發(fā)的項目中需要提供一個(gè)暴露的接口來(lái)驗證微信服務(wù)器,主要是驗證微信公眾號網(wǎng)頁(yè)上填寫(xiě)的token驗證。官方文檔說(shuō)明如下:

  

  所以在項目中,放置在配置文件或常量池中的token必須是微信公眾號訪(fǎng)問(wèn)中填寫(xiě)的token的字符串。如果輸入不同或者方法中的解密比較有問(wèn)題,在網(wǎng)頁(yè)上點(diǎn)擊確定,就會(huì )出現“失敗”字樣。

  

  

  2.3 微信開(kāi)發(fā)者工具準備

  下載微信開(kāi)發(fā)者工具。

  點(diǎn)擊下載微信開(kāi)發(fā)者工具

  

  下載完成后掃碼登錄

  

  選擇微信公眾號網(wǎng)頁(yè)開(kāi)發(fā)

  

  

  此工具是后續開(kāi)發(fā)中訪(fǎng)問(wèn)URL和前端調試必不可少的工具。

  2.3 Oauth2 授權

  此時(shí)測試號已經(jīng)配置好了,那么接下來(lái)我們如何開(kāi)發(fā)呢?在微信公眾號頁(yè)面,部分頁(yè)面需要根據用戶(hù)的身份回顯不同的信息,比如用戶(hù)的還款清單。這些實(shí)現首先需要獲取個(gè)人信息然后與數據庫進(jìn)行交互,需要獲取用戶(hù)的唯一標識。在微信中,每個(gè)人都有并且只有一個(gè)唯一標識openId。這個(gè)openId需要通過(guò)微信的授權和回調獲取。同時(shí),微信公開(kāi)文檔上也有詳細的授權方式介紹。如何授權可以根據自己的業(yè)務(wù)需要使用。在實(shí)際業(yè)務(wù)中,根據項目的特點(diǎn)固化不同的用戶(hù)。我們所做的是將用戶(hù)固化到數據庫中,生成一個(gè) UUID,并將 UUID 放入 cookie。授權非常重要。通過(guò)它的控件,我們可以通過(guò)獲取當前用戶(hù)的openid來(lái)比較用戶(hù)是會(huì )員還是普通會(huì )員,是非管理員還是管理員等。這在頁(yè)面跳轉中起著(zhù)至關(guān)重要的作用。同時(shí),在代碼中,一些靜態(tài)頁(yè)面可能不一定需要授權,任何人都可以查看。所以在代碼中,我使用了一個(gè)過(guò)濾器,直接在前臺發(fā)布了一系列.css、.js、.html等。特殊要求,我拉過(guò)來(lái),要求微信授權。例如,我在項目中。 .go請求中需要驗證,通過(guò)微信回調獲取當前用戶(hù)信息,固化用戶(hù)。代碼如下:

  @WebFilter(urlPatterns = "/*", filterName = "authFilter")

public class AuthFilter implements Filter {

private final Logger logger = LoggerFactory.getLogger(AuthFilter.class);

@Autowired

private GeneralConfigService gcService;

@Autowired

private WxUserVerify wxUserVerify;

@Override

public void init(FilterConfig filterConfig) throws ServletException {

}

@Override

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)

throws IOException, ServletException {

HttpServletRequest request = (HttpServletRequest) servletRequest;

HttpServletResponse response = (HttpServletResponse) servletResponse;

try {

String url = request.getRequestURI();

logger.info("URL:" + url);

// 1.請求內容為WEB靜態(tài)內容時(shí)直接放行

if (StringUtil.separatorEndWith(gcService.getStaticResourceConfig(), url)) {

chain.doFilter(servletRequest, servletResponse);

return;

}

// 2.不是靜態(tài)資源進(jìn)行驗證

if(!checkUrl(request, response, url)){

return;

}

chain.doFilter(servletRequest, servletResponse);

return;

} catch (FilterException e1) {

//自定義異常,這里可以直接把錯誤信息拋出去,不需要記錄日志,因為這里是業(yè)務(wù)異常。

ResponseUtil.error(response, e1.getMessage());

} catch (Exception e2) {

//無(wú)法捕捉的異常,不能直接把錯誤信息拋出去,需要包裝下錯誤信息

logger.error(e2.getMessage(), e2);

ResponseUtil.error(response, "系統異常,請稍后再試...");

}

}

/**

* 與數據庫配置url進(jìn)行匹配

* @param request

* @param response

* @param url

* @return

*/

private boolean checkUrl(HttpServletRequest request, HttpServletResponse response, String url) {

boolean passFlag=true;

//與數據庫進(jìn)行匹配

Map urlConfig = getUrlConfig();

//比較匹配項

String substring = url.substring(url.lastIndexOf("/") + 1);

if (!urlConfig.containsKey(substring)) {

return passFlag;

}

CallBackMsg msg = wxUserVerify.doVerify(request, response);

if (msg.getResultCode().equals(CallBackMsg.WX_VALID_CONTINUE)) {

passFlag=false;

} else if (msg.getResultCode().equals(Const.ERROR_CODE)) {

throw new FilterException(FilterExceptionEnum.ERROR_WX_VALID_FAILE);

}

return passFlag;

}

/**

* 獲取地址配置信息

* @return

*/

private Map getUrlConfig() {

// 3.獲取需要驗證用戶(hù)的請求配置

Map configAddressList = gcService.getConfigAddressList();

logger.info(configAddressList.toString());

if (configAddressList.isEmpty()) {

logger.error("urlValidConfig為空,請檢查!");

throw new FilterException(FilterExceptionEnum.ERROR_VALIDCONF_NULL);

}

return configAddressList;

}

@Override

public void destroy() {

}

}

  通過(guò)創(chuàng )建一個(gè)類(lèi)來(lái)實(shí)現Filter過(guò)濾器進(jìn)行驗證,@WebFilter(urlPatterns = "/*", filterName = "authFilter")對所有請求進(jìn)行過(guò)濾攔截,其中封裝的方法當是特定請求時(shí)會(huì )被拉取申請授權

  private CallBackMsg impower(HttpServletRequest request, HttpServletResponse response) {

CallBackMsg msg = new CallBackMsg();

String code = request.getParameter("code");

try {

// 從配置獲取access_token

String appId = getWxParams("wxAppid");

String secret = getWxParams("wxSecret");

String accessTokenUrl = gcService.getUrlWxFwGetToken() + "?appid=" + appId + "&secret=" + secret + "&code="

+ code + "&grant_type=authorization_code";

logger.info("accessTokenUrl:" + accessTokenUrl);

String accessTokenResult = "";

if (StringUtil.isEmpty(proxyFlag)) {

proxyFlag = gcService.getProxyFlag();

}

if (Const.PROXY_FLAG_USED.equals(proxyFlag)) {

accessTokenResult = HttpUtils.sendPostHttpsViaProxy(accessTokenUrl, "", gcService.getProxyIp(),

gcService.getProxyPort());

} else {

accessTokenResult = HttpUtils.sendPostHttps(accessTokenUrl, "");

}

logger.info("accessTokenResult:" + accessTokenResult);

JSONObject accessTokenJson = JSONObject.parseObject(accessTokenResult);

String accessToken = accessTokenJson.getString("access_token");

logger.info("accessToken:" + accessToken);

String openid = accessTokenJson.getString("openid");

logger.info("openid:" + openid);

// 查詢(xún)數據庫中的用戶(hù)數據

String reqUrl = gcService.getSkylarkServiceUrl() + "wechat/searchwxuserinfo";

ResponseDto responseQuery = this.restInvoke(reqUrl, getQueryParam(openid, null, 1));

String userInfoDb = responseQuery.getRspMesg();

JSONObject userInfoDbJson = JSONObject.parseObject(userInfoDb);

String uuid = "";

// 數據庫不存在該用戶(hù)則保存數據庫,存在則返回已存在的UUID

if (StringUtils.isEmpty(userInfoDbJson)) {

// 查詢(xún)微信中的用戶(hù)數據

uuid = UUIDGenerator.genUUID();

// 獲取用戶(hù)信息

String userInfoUrl = gcService.getUrlWxFwGetUser() + "?access_token=" + accessToken + "&openid="

+ openid + "&lang=zh_CN";

logger.info("userInfoUrl:" + userInfoUrl);

String userInfoResult = "";

if (Const.PROXY_FLAG_USED.equals(proxyFlag)) {

userInfoResult = HttpUtils.sendPostHttpsViaProxy(userInfoUrl, "", gcService.getProxyIp(),

gcService.getProxyPort());

} else {

userInfoResult = HttpUtils.sendPostHttps(userInfoUrl, "");

}

logger.info("userInfoResult:" + userInfoResult);

JSONObject userInfoJson = JSONObject.parseObject(userInfoResult);

// 固化用戶(hù)

String addReq = gcService.getSkylarkServiceUrl() + "wechat/addwxuserinfo";

ResponseDto addResp = this.restInvoke(addReq,

getEntityParam(uuid, openid, userInfoJson));

// 失敗另處理

if (!(Const.SUCCESS_CODE).equals(addResp.getRspCode())) {

// 保存數據失敗,認證失敗

msg.setResultCode(Const.ERROR_CODE);

return msg;

}

} else {

uuid = userInfoDbJson.getString("id");

}

// 權限:本項目中的類(lèi)都可以訪(fǎng)問(wèn)該cookie,存儲到客戶(hù)端

Cookie cookie = new Cookie(Const.TOKEN, uuid);

cookie.setPath("/");

response.addCookie(cookie);

//將token存入session

HttpSession session = request.getSession();

session.setAttribute("authToken",uuid);

} catch (IOException e) {

logger.error(e.getMessage());

}

msg.setResultCode(Const.SUCCESS_CODE);

return msg;

}

  因為項目中使用了代理服務(wù)器,不需要本地開(kāi)發(fā),所以方法有點(diǎn)亂,但是大體思路是客戶(hù)端發(fā)起帶有特殊后綴的請求時(shí),被過(guò)濾器攔截接下來(lái),與微信服務(wù)器進(jìn)行交互授權的過(guò)程。授權成功后,向微信提供回調地址,并將微信帶回的用戶(hù)信息保存在表中。同時(shí),當前用戶(hù)在庫表中生成的唯一標識標識存儲在cookie域中。

  

  這樣就可以將獲取到的openid放入cookie中了。那么這個(gè)openId就可以固化了,也就是存儲在數據庫中。在會(huì )話(huà)中,如果點(diǎn)擊某個(gè)頁(yè)面需要使用微信授權,可以先從cookie域中獲取。如果cookie不可用,則向微信發(fā)起授權請求,獲取openid后,存儲cookie和curing。有一些步驟可以實(shí)現這一點(diǎn)。微信開(kāi)放平臺上有相關(guān)的demo。如果您需要我提供它們,請留言。后續授權碼我會(huì )貼出來(lái)供大家參考。

0 個(gè)評論

要回復文章請先登錄注冊


官方客服QQ群

微信人工客服

QQ人工客服


線(xiàn)

亚洲国产精品无码久久大片,亚洲AV无码乱码麻豆精品国产,亚洲品质自拍网站,少妇伦子伦精品无码STYLES,国产精久久久久久久