官方文檔

網(wǎng)頁(yè)授權(quán)https://developers.weixin.qq.com/doc/" />

国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

15158846557 在線咨詢 在線咨詢
15158846557 在線咨詢
所在位置: 首頁(yè) > 營(yíng)銷資訊 > 網(wǎng)站運(yùn)營(yíng) > 【微信登錄】網(wǎng)頁(yè)授權(quán)與APP授權(quán)

【微信登錄】網(wǎng)頁(yè)授權(quán)與APP授權(quán)

時(shí)間:2022-08-10 15:30:01 | 來(lái)源:網(wǎng)站運(yùn)營(yíng)

時(shí)間:2022-08-10 15:30:01 來(lái)源:網(wǎng)站運(yùn)營(yíng)

前言

微信APP支付,微信授權(quán),微信JSAPI支付,微信退款,支付寶APP支付,支付寶手機(jī)網(wǎng)站支付,支付寶退款。筆者都放到公眾號(hào): JAVA大賊船。微信搜一搜,方便以后開(kāi)發(fā)用哦!

官方文檔

網(wǎng)頁(yè)授權(quán)

https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html

APP授權(quán)

https://developers.weixin.qq.com/doc/oplatform/Mobile_App/WeChat_Login/Development_Guide.html

iOS 接入指南

https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Access_Guide/iOS.html

Android 接入指南

https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Access_Guide/Android.html

流程步驟說(shuō)明(具體說(shuō)明參考官方文檔,這里只描述大體)

1、引導(dǎo)用戶進(jìn)入授權(quán)頁(yè)面同意授權(quán),獲取 code
2、通過(guò) code 換取網(wǎng)頁(yè)授權(quán) access_token(與基礎(chǔ)支持中的 access_token 不同)
3、如果需要,開(kāi)發(fā)者可以刷新網(wǎng)頁(yè)授權(quán) access_token,避免過(guò)期
4、通過(guò)網(wǎng)頁(yè)授權(quán) access_token 和 openid 獲取用戶基本信息(支持 UnionID 機(jī)制)
疑問(wèn) 1:scope 為 snsapi_base 和 scope 為 snsapi_userinfo 的區(qū)別?

snsapi_base 是靜默授權(quán)并自動(dòng)跳轉(zhuǎn)到回調(diào)頁(yè)的,snsapi_userinfo 是需要用戶手動(dòng)同意。
疑問(wèn) 2:網(wǎng)頁(yè)授權(quán) access_token 和普通 access_token 的區(qū)別?

普通 access_token 獲取用戶信息時(shí),如果用戶未關(guān)注,信息獲取就為空。而網(wǎng)頁(yè)授權(quán) access_token 的獲取,只要用戶許可,就可以獲得,不論用戶是否關(guān)注。
疑問(wèn) 3:UnionID 和 openid 的區(qū)別?

unionid 對(duì)同一個(gè)微信開(kāi)放平臺(tái)下的不同應(yīng)用(移動(dòng)應(yīng)用、網(wǎng)站應(yīng)用和公眾帳號(hào))都是相同的。
而 openid 對(duì)同一個(gè)微信開(kāi)放平臺(tái)下的不同應(yīng)用都是不相同的,如用戶授權(quán)應(yīng)用 A 和應(yīng)用 B,那么用戶的兩個(gè) openid 是不相同的,并且一個(gè)應(yīng)用對(duì)應(yīng)一個(gè) openid,如用戶在次授權(quán)給應(yīng)用 A,openid 不變。
疑問(wèn) 4:關(guān)于UnionID機(jī)制

即如果開(kāi)發(fā)者有多個(gè)公眾號(hào),或在公眾號(hào)、移動(dòng)應(yīng)用之間統(tǒng)一用戶帳號(hào)的需求,需要前往微信開(kāi)放平臺(tái)(http://open.weixin.qq.com)綁定公眾號(hào)后,才可利用UnionID機(jī)制來(lái)滿足上述需求。

踩過(guò)的坑

解決:在公眾號(hào)設(shè)置-功能設(shè)置-網(wǎng)頁(yè)授權(quán),配置前端存放txt文件的路徑,如http://www.xxx.com/static,然后點(diǎn)擊提交,可以事先測(cè)一下能不能訪問(wèn)到txt的內(nèi)容。
解決:前往微信開(kāi)放平臺(tái),綁定該公眾號(hào),大功告成
  1. 第三方發(fā)起微信授權(quán)登錄請(qǐng)求,微信用戶允許授權(quán)第三方應(yīng)用后,微信會(huì)拉起應(yīng)用或重定向到第三方網(wǎng)站,并且?guī)鲜跈?quán)臨時(shí)票據(jù) code 參數(shù);
  2. 通過(guò) code 參數(shù)加上 AppID 和 AppSecret 等,通過(guò) API 換取 access_token;
  3. 通過(guò) access_token 進(jìn)行接口調(diào)用,獲取用戶基本數(shù)據(jù)資源或幫助用戶實(shí)現(xiàn)基本操作。



準(zhǔn)備工作

代碼實(shí)現(xiàn)(含 APP 和 H5)

application.yml

# 微信相關(guān)配置wx: #商戶 ID MCH_ID: # 項(xiàng)目基礎(chǔ)域名 BASEURL: #微信登錄-用戶同意后回調(diào)域名(前端域名) URL: # 公眾號(hào)APP_ID H_APP_ID: # 公眾號(hào)秘鑰 H_APP_SECRET: # app的APP_ID A_APP_ID: # APP的 秘鑰 A_APP_SECRET: #微信登錄-微信授權(quán)基本地址 LOGIN_AUTH_BASE_URL: https://open.weixin.qq.com/connect/oauth2/authorize? #微信登錄-獲取ACCESS_TOKEN的URL LOGIN_ACCESS_TOKEN_URL: https://api.weixin.qq.com/sns/oauth2/access_token? #微信登錄-獲取登錄人信息的url LOGIN_USER_INFO_URL: https://api.weixin.qq.com/sns/userinfo? #微信登錄-用戶同意后回調(diào)地址(前端地址) LOGIN_RETURN_URL: ${wx.URL}/static/weixinShouQuan.html #微信登錄-應(yīng)用授權(quán)作用域,snsapi_base (不彈出授權(quán)頁(yè)面,直接跳轉(zhuǎn),只能獲取用戶openid), snsapi_userinfo #(彈出授權(quán)頁(yè)面,可通過(guò)openid拿到昵稱、性別、所在地。并且,即使在未關(guān)注的情況下,只要用戶授權(quán),也能獲取其信息 ) SCOPE: snsapi_userinfoYmlParament

/** * 獲取yml參數(shù)實(shí)體 */@Component@Datapublic class YmlParament { /*微信相關(guān)字段*/ @Value("${wx.BASEURL}") private String baseurl; @Value("${wx.H_APP_ID}") private String h_app_id; @Value("${wx.A_APP_ID}") private String a_app_id; @Value("${wx.H_APP_SECRET}") private String h_app_secret; @Value("${wx.A_APP_SECRET}") private String a_app_secret; @Value("${wx.LOGIN_ACCESS_TOKEN_URL}") private String login_access_token_url; @Value("${wx.LOGIN_USER_INFO_URL}") private String login_user_info_url; @Value("${wx.LOGIN_AUTH_BASE_URL}") private String login_auth_base_url; @Value("${wx.LOGIN_RETURN_URL}") private String login_return_url; @Value("${wx.SCOPE}") private String scope;} H5 獲取 code

前端通過(guò)后臺(tái)拿到授權(quán)url,然后前端請(qǐng)求該url得到code再請(qǐng)求后臺(tái)

WxController

@ApiOperation("獲取授權(quán)url") @PostMapping("/getWeiXinLoginUrl") public R getWeiXinLoginUrl() throws Exception { String url = ymlParament.getLogin_auth_base_url() + "appid=" + ymlParament.getH_app_id()+ "&redirect_uri=" + ymlParament.getLogin_return_url()+ "&response_type=code"+ "&scope=snsapi_userinfo" + "&state=STATE#wechat_redirect"; //這里的R是自己自定義的 return R.ok().data("redirectUrl", url); }


APP 獲取 code

iOS 平臺(tái)應(yīng)用授權(quán)登錄接入代碼示例(請(qǐng)參考 iOS 接入指南):

-(void)sendAuthRequest{ //構(gòu)造SendAuthReq結(jié)構(gòu)體 SendAuthReq* req =[[[SendAuthReq alloc]init]autorelease]; req.scope = @"snsapi_userinfo"; req.state = @"123"; //第三方向微信終端發(fā)送一個(gè)SendAuthReq消息結(jié)構(gòu) [WXApi sendReq:req];}Android 平臺(tái)應(yīng)用授權(quán)登錄接入代碼示例(請(qǐng)參考 Android 接入指南):

{ // send oauth request Final SendAuth.Req req = new SendAuth.Req(); req.scope = "snsapi_userinfo"; req.state = "wechat_sdk_demo_test"; api.sendReq(req);}


通過(guò) code 換取網(wǎng)頁(yè)授權(quán) access_token,然后通過(guò) access_token 和 openid 拉取用戶信息

WxController

/*H5和app都可以調(diào)用*/ @ApiOperation("獲取微信用戶信息") @PostMapping(value = "/getWxUserInFo") public R getWxUserInFo(@RequestBody String body) throws Exception { String state = JacksonUtil.parseString(body, "state"); String code = JacksonUtil.parseString(body, "code"); //標(biāo)志哪一個(gè)應(yīng)用,用來(lái)獲取對(duì)應(yīng)的appid和appsecret Integer openIdType = JacksonUtil.parseInteger(body, "openIdType"); //1、獲取code if(IsNull.isNull(code) || IsNull.isNull(state)) { return R.error("參數(shù)不能為空"); } //2、通過(guò)code獲取accesstoken,UserWxOpenidEums是用來(lái)記錄應(yīng)用的,如type1是xxAPP,type2是xx服務(wù)號(hào) JSONObject accessToken=WxUtils.getAccessTokenByCode(code, openIdType==UserWxOpenidEums.TYPE_1.getKey()?ymlParament.getA_app_id():ymlParament.getH_app_id(),openIdType==UserWxOpenidEums.TYPE_1.getKey()?ymlParament.getA_app_secret():ymlParament.getH_app_secret(),ymlParament.getLogin_access_token_url()); //3、獲取用戶信息 JSONObject userinfo=WxUtils.getUserinfo(openIdType==UserWxOpenidEums.TYPE_1.getKey()?ymlParament.getA_app_id():ymlParament.getH_app_id(),accessToken.getString("openid"), accessToken.getString("access_token"), ymlParament.getLogin_user_info_url()); if(!IsNull.isNull(userinfo.getString("errcode"))){ return R.error(userinfo.getString("errmsg")); } return R.ok().data("token", token).data("userinfo",userinfo);}WxUtils

/** * =============>>登錄<<============= * 第二步 * 通過(guò)code獲取access_token * 正確時(shí)返回的JSON數(shù)據(jù)包如下: * { "access_token":"ACCESS_TOKEN", "expires_in":7200, "refresh_token":"REFRESH_TOKEN", "openid":"OPENID", "scope":"SCOPE" } */ public static JSONObject getAccessTokenByCode(String code,String appId,String appSecret,String login_access_token_url) throws Exception { Map<String, String> map = new HashMap<String, String>(); map.put("appid",appId); map.put("secret",appSecret); map.put("code",code); map.put("grant_type","authorization_code"); return (JSONObject)JSON.parse(HttpUtil.get(login_access_token_url, map)); } /** * =============>>登錄<<============= * 第三步:刷新access_token(如果需要) * 正確時(shí)返回的JSON數(shù)據(jù)包如下: * { "access_token":"ACCESS_TOKEN", "expires_in":7200, "refresh_token":"REFRESH_TOKEN", "openid":"OPENID", "scope":"SCOPE" } */ public static JSONObject refreshAccessToken(String appid,String refresh_token) throws Exception { Map<String, String> map = new HashMap<>(); map.put("appid",appid); map.put("grant_type","refresh_token"); map.put("refresh_token",refresh_token); return (JSONObject)JSON.parse(HttpUtil.get("https://api.weixin.qq.com/sns/oauth2/refresh_token?", map)); } /** * =============>>登錄<<============= * 第四部,獲取用戶信息 * 通過(guò)code獲取access_token * 正確時(shí)返回的JSON數(shù)據(jù)包如下: * { "openid":" OPENID", "nickname": NICKNAME, "sex":"1", "province":"PROVINCE", "city":"CITY", "country":"COUNTRY", "headimgurl": "http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46", "privilege":[ "PRIVILEGE1" "PRIVILEGE2" ], "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" } * @throws Exception */ public static JSONObject getUserinfo(String appid,String openid,String accessToken,String login_user_info_url) throws Exception { //先判斷下accessToken是否有效 HashMap<String, String> param =new HashMap<String, String>(); param.put("access_token", accessToken); param.put("openid", openid); JSONObject check=(JSONObject)JSON.parse(HttpUtil.get("https://api.weixin.qq.com/sns/auth?access_token="+accessToken+"&openid="+openid, param)); //檢驗(yàn)授權(quán)憑證(access_token)是否有效,如果accessToken失效了,則刷新accessToken if(!check.getString("errcode").equals("0")) { accessToken=refreshAccessToken(appid, accessToken).getString("refresh_token"); } param =new HashMap<String, String>(); param.put("openid",openid); param.put("access_token",accessToken); param.put("lang","zh_CN"); return (JSONObject) JSON.parse(HttpUtil.get(login_user_info_url, param)); }HttpUtil

public static String get(String urlStr, Map<String, String> parameters) throws IOException { URL url = new URL(urlStr); HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(); httpURLConnection.setDoInput(true); httpURLConnection.setDoOutput(true); // 設(shè)置該連接是可以輸出的 httpURLConnection.setRequestMethod("GET"); // 設(shè)置請(qǐng)求方式 httpURLConnection.setRequestProperty("charset", "utf-8"); PrintWriter pw = new PrintWriter(new BufferedOutputStream(httpURLConnection.getOutputStream())); StringBuffer parameter = new StringBuffer(); parameter.append("1=1"); for (Entry<String, String> entry : parameters.entrySet()) { parameter.append("&" + entry.getKey() + "=" + entry.getValue()); } pw.write(parameter.toString());// 向連接中寫數(shù)據(jù)(相當(dāng)于發(fā)送數(shù)據(jù)給服務(wù)器) pw.flush(); pw.close(); BufferedReader br = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(), "utf-8")); String line = null; StringBuilder sb = new StringBuilder(); while ((line = br.readLine()) != null) { // 讀取數(shù)據(jù) sb.append(line + "/n"); } br.close(); return sb.toString(); }JacksonUtil

public class JacksonUtil { public static String parseString(String body, String field) { ObjectMapper mapper = new ObjectMapper(); JsonNode node; try { node = mapper.readTree(body); JsonNode leaf = node.get(field); if (leaf != null) { return leaf.asText(); } } catch (IOException e) { e.printStackTrace(); } return null; } public static Integer parseInteger(String body, String field) { ObjectMapper mapper = new ObjectMapper(); JsonNode node; try { node = mapper.readTree(body); JsonNode leaf = node.get(field); if (leaf != null) { return leaf.asInt(); } } catch (IOException e) { e.printStackTrace(); } return null; }}



關(guān)鍵詞:授權(quán)

74
73
25
news

版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點(diǎn)擊下載Chrome瀏覽器
關(guān)閉