微信掃一掃登錄網(wǎng)站

微信網(wǎng)站掃一掃登錄

個(gè)人blog+bbs www.youngboy.vip


上手須知

要想使用微信掃一掃就可以登錄網(wǎng)站,首先要有微信開(kāi)發(fā)平臺(tái)賬號(hào)址貌,并且通過(guò)開(kāi)發(fā)者資質(zhì)認(rèn)證(認(rèn)證需要通過(guò)審核练对,審核費(fèi)300人民幣),然后添加網(wǎng)頁(yè)應(yīng)用準(zhǔn)備網(wǎng)站信息登記表等信息提價(jià)審核虚青,有公眾號(hào)的可以綁定公眾號(hào)棒厘,最終你會(huì)得到 appid 和 appsecret 然后就可以愉快的玩耍了

科普微信授權(quán)原理

微信用戶(hù)->第三方應(yīng)用: 請(qǐng)求登錄第三方應(yīng)用
第三方應(yīng)用->微信開(kāi)發(fā)平臺(tái): 請(qǐng)求oauth2授權(quán)
微信開(kāi)發(fā)平臺(tái)->微信用戶(hù): 請(qǐng)求用戶(hù)確認(rèn)
微信用戶(hù)->微信開(kāi)發(fā)平臺(tái): 用戶(hù)確認(rèn)
微信開(kāi)發(fā)平臺(tái)-> 第三方應(yīng)用: 拉起第三方應(yīng)用或重定向到第三方的服務(wù)器奢人,并帶上code
第三方應(yīng)用 -> 微信開(kāi)發(fā)平臺(tái): 通過(guò)code加上appid appsecret獲取access_token
微信開(kāi)發(fā)平臺(tái) -> 第三方應(yīng)用: 返回用戶(hù)相關(guān)信息

前端的打開(kāi)方式

前端有兩種打開(kāi)方式

  1. 通過(guò)重定向到微信的頁(yè)面然后用戶(hù)掃描二維碼授權(quán)淆院,再重定向回第三方網(wǎng)站
  2. 通過(guò)js直接顯示二維碼登錄土辩,不用跳轉(zhuǎn)微信頁(yè)面

第一種方式是通過(guò)后臺(tái)重定向過(guò)去的所以前端只需要寫(xiě)個(gè)鏈接就行了宪赶,第二種方式是在頁(yè)面上直接顯示二維碼登錄減少了跳頁(yè)面的時(shí)間,這種方式需要在網(wǎng)頁(yè)上用js實(shí)現(xiàn)脯燃,一般第二種用的比較多

使用js顯示微信掃一掃二維碼的打開(kāi)方式

步驟1:在頁(yè)面中先引入如下JS文件(支持https):

https://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js

步驟2:在需要使用微信登錄的地方實(shí)例以下JS對(duì)象:

var obj = new WxLogin({
     id:"login_container", // 需要顯示的容器id
     appid: "",  // 公眾號(hào)appid wx*******
     scope: "snsapi_login",  // 網(wǎng)頁(yè)默認(rèn)即可
     redirect_uri: "", // 授權(quán)成功后回調(diào)的url
     state: "", // 可設(shè)置為簡(jiǎn)單的隨機(jī)數(shù)加session用來(lái)校驗(yàn)
     style: "black", // 提供"black"、"white"可選蒙保。二維碼的樣式
     href: "" // 外部css文件url辕棚,需要https
});

參數(shù)說(shuō)明

參數(shù) 是否必須 說(shuō)明
self_redirect true:手機(jī)點(diǎn)擊確認(rèn)登錄后可以在 iframe 內(nèi)跳轉(zhuǎn)到 redirect_uri,false:手機(jī)點(diǎn)擊確認(rèn)登錄后可以在 top window 跳轉(zhuǎn)到 redirect_uri邓厕。默認(rèn)為 false逝嚎。
id 第三方頁(yè)面顯示二維碼的容器id
appid 應(yīng)用唯一標(biāo)識(shí),在微信開(kāi)放平臺(tái)提交應(yīng)用審核通過(guò)后獲得
scope 應(yīng)用授權(quán)作用域补君,擁有多個(gè)作用域用逗號(hào)(,)分隔,網(wǎng)頁(yè)應(yīng)用目前僅填寫(xiě)snsapi_login即可
redirect_uri 重定向地址昧互,需要進(jìn)行UrlEncode
state 用于保持請(qǐng)求和回調(diào)的狀態(tài)挽铁,授權(quán)請(qǐng)求后原樣帶回給第三方。該參數(shù)可用于防止csrf攻擊(跨站請(qǐng)求偽造攻擊)敞掘,建議第三方帶上該參數(shù)叽掘,可設(shè)置為簡(jiǎn)單的隨機(jī)數(shù)加session進(jìn)行校驗(yàn)
style 提供"black"、"white"可選玖雁,默認(rèn)為黑色文字描述
href 自定義樣式鏈接更扁,第三方可根據(jù)實(shí)際需求覆蓋默認(rèn)樣式

用戶(hù)點(diǎn)擊確認(rèn)授權(quán)后網(wǎng)頁(yè)會(huì)自動(dòng)跳轉(zhuǎn)redirect_uri

前端掃碼分析

https://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js 的代碼

!function(a, b, c) {
    function d(a) {
        var c = "default";
        a.self_redirect === !0 ? c = "true": a.self_redirect === !1 && (c = "false");
        var d = b.createElement("iframe"),
        e = "https://open.weixin.qq.com/connect/qrconnect?appid=" + a.appid + "&scope=" + a.scope + "&redirect_uri=" + a.redirect_uri + "&state=" + a.state + "&login_type=jssdk&self_redirect=" + c;
        e += a.style ? "&style=" + a.style: "",
        e += a.href ? "&href=" + a.href: "",
        d.src = e,
        d.frameBorder = "0",
        d.allowTransparency = "true",
        d.scrolling = "no",
        d.width = "300px",
        d.height = "400px";
        var f = b.getElementById(a.id);
        f.innerHTML = "",
        f.appendChild(d)
    }
    a.WxLogin = d
} (window, document);

上段代碼主要功能是根據(jù)用戶(hù)配置的消息在頁(yè)面上嵌入一個(gè)iframe,我們看到的二維碼是iframe和請(qǐng)掃描等提示語(yǔ)都是iframe中的

這里先給大家一個(gè)鏈接看看 點(diǎn)我
打開(kāi)iframe的鏈接返回的是一個(gè)網(wǎng)頁(yè),再打開(kāi)游覽器的開(kāi)發(fā)者工具可以看到一個(gè)長(zhǎng)連接請(qǐng)求

https://long.open.weixin.qq.com/connect/l/qrconnect?uuid=081ciRVWnFkIOwL8&_=1534297144336

這個(gè)請(qǐng)求帶有兩個(gè)參數(shù)一個(gè)是 uuid 還有一個(gè) 是 _ 看樣子應(yīng)該是時(shí)間戳,這個(gè)請(qǐng)求在沒(méi)掃描之前一直是阻塞的,如果27秒沒(méi)有掃碼會(huì)自動(dòng)斷開(kāi)連接浓镜,并且返回一段js代碼

window.wx_errcode=408;window.wx_code='';

再來(lái)看看網(wǎng)頁(yè)中嵌入的一段代碼,這里我省略了一些代碼只留下比較重要的

!function() {
    function a(d) {
        jQuery.ajax({
            type: "GET",
            url: "https://long.open.weixin.qq.com/connect/l/qrconnect?uuid=011ZJt4N2TyhElXu" + (d ? "&last=" + d: ""),
            dataType: "script", //這里是script類(lèi)型
            cache: !1,
            timeout: 6e4,
            success: function(d, e, f) {
                var g = window.wx_errcode;//這里為什么是window.wx_errcode呢 因?yàn)榉祷氐母袷绞莝cript 內(nèi)容是 window.wx_errcode=408;window.wx_code='';
                switch (g) {
                case 405://如果是405證明用戶(hù)已經(jīng)同意授權(quán)登錄 用js重定向并帶上code
                    var h = "http://www.reibang.com/users/auth/wechat/callback";
                    h = h.replace(/&/g, "&"),
                    h += (h.indexOf("?") > -1 ? "&": "?") + "code=" + wx_code + "&state=123";
                    var i = b("self_redirect");
                    if (c) if ("true" !== i && "false" !== i) try {
                        document.domain = "qq.com";
                        var j = window.top.location.host.toLowerCase();
                        j && (window.location = h)
                    } catch(k) {
                        window.top.location = h
                    } else if ("true" === i) try {
                        window.location = h
                    } catch(k) {
                        window.top.location = h
                    } else window.top.location = h;
                    else window.location = h;
                    break;
                case 404:
                    jQuery(".js_status").hide(),
                    jQuery("#wx_after_scan").show(),
                    setTimeout(a, 100, g);
                    break;
                case 403:
                    jQuery(".js_status").hide(),
                    jQuery("#wx_after_cancel").show(),
                    setTimeout(a, 2e3, g);
                    break;
                case 402:
                case 500:
                    window.location.reload();
                    break;
                case 408:
                    setTimeout(a, 2e3)
                }
            },
            error: function(b, c, d) {
                var e = window.wx_errcode;
                408 == e ? setTimeout(a, 5e3) : setTimeout(a, 5e3, e)
            }
        })
    }
    ...
} ();

上面的代碼是一段自執(zhí)行函數(shù)溃列,鏈接一打開(kāi)就會(huì)執(zhí)行,在用戶(hù)掃碼之前請(qǐng)求是阻塞的success回調(diào)都不會(huì)執(zhí)行膛薛,如果用戶(hù)一直沒(méi)有掃描二維碼听隐,請(qǐng)求在27秒內(nèi)就會(huì)斷開(kāi)鏈接這時(shí)就會(huì)去執(zhí)行success回調(diào)函數(shù)并且重新發(fā)起一個(gè)長(zhǎng)連接重復(fù)以上步驟直到返回405

網(wǎng)頁(yè)中的二維碼解析后的結(jié)果是

https://open.weixin.qq.com/connect/confirm?uuid=0618LnlRCFd-jYeo

這個(gè)鏈接只有一個(gè)參數(shù)并且uuid和長(zhǎng)連接請(qǐng)求的uuid是相同的,用游覽器打開(kāi)會(huì)提示Scope 參數(shù)錯(cuò)誤或沒(méi)有 Scope 權(quán)限相叁,只能用微信打開(kāi)才有用遵绰,微信的包不好抓希望有大神能夠指點(diǎn)指點(diǎn)

后端的打開(kāi)方式

重定向到微信頁(yè)面的打開(kāi)方式

登錄你的網(wǎng)站應(yīng)用
https://xxx.xxx.com/wechat/login.do
打開(kāi)后需要重定向至微信的地址并帶上必要的參數(shù)

https://open.weixin.qq.com/connect/qrconnect?
appid=wxbdc5610cc59c1631
&
redirect_uri=https%3A%2F%2Fxxx.xxx.com%2Fwechat%2Fcallback.do
&
response_type=code
&
scope=snsapi_login
&
state=3d6be0a4035d839573b04816624a415e#wechat_redirect

這里需要變的參數(shù)是appid和redirect_url

訪(fǎng)問(wèn)以上鏈接微信開(kāi)發(fā)平臺(tái)會(huì)重定向到redirect_uri的網(wǎng)址上,并且?guī)?code>code和state參數(shù)增淹,如果用戶(hù)沒(méi)有授權(quán)就不會(huì)有code參數(shù)椿访,僅會(huì)帶上state參數(shù)

https://xxx.xxx.com?code=xxx&state=xxx

后臺(tái)根據(jù)code獲取用戶(hù)信息封裝

獲取用戶(hù)信息的步驟

  • 通過(guò)code獲取access_token
  • 通過(guò)access_token調(diào)用接口

這里使用了weixin-java-tools工具來(lái)獲取用戶(hù)信息
github地址 傳送門(mén)

public WxMpUser getWxUser(String code) {
        if (code == null) {
            return null;
        }
        WxMpOAuth2AccessToken wxMpOAuth2AccessToken = null;
        WxMpUser wxMpUser = null;
        try {
            wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code);
            wxMpOAuth2AccessToken = wxMpService.oauth2refreshAccessToken(wxMpOAuth2AccessToken.getRefreshToken());
            wxMpUser = wxMpService.oauth2getUserInfo(wxMpOAuth2AccessToken, null);
        } catch (WxErrorException e) {
            return null;
        }

        return wxMpUser;
    }

社區(qū)討論

Java 長(zhǎng)連接模擬微信登錄

[圖片上傳失敗...(image-6193f9-1557819001579)]

實(shí)現(xiàn)原理

使用Servlet3異步接口實(shí)現(xiàn)非阻塞長(zhǎng)連接接口, 異步上下文對(duì)象使用 ScheduledExecutorService 線(xiàn)程池定時(shí)調(diào)度 事件總線(xiàn)使用了 guava 中的 EventBus 實(shí)現(xiàn)

有興趣可以去瞧瞧虑润,目前oauth2+openId掃碼登錄正在開(kāi)發(fā)中... 歡迎fork添加代碼

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末成玫,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子拳喻,更是在濱河造成了極大的恐慌哭当,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,576評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件冗澈,死亡現(xiàn)場(chǎng)離奇詭異钦勘,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)亚亲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)彻采,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人捌归,你說(shuō)我怎么就攤上這事肛响。” “怎么了惜索?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,017評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵特笋,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我巾兆,道長(zhǎng)猎物,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,626評(píng)論 1 296
  • 正文 為了忘掉前任角塑,我火速辦了婚禮霸奕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘吉拳。我一直安慰自己质帅,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著煤惩,像睡著了一般嫉嘀。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上魄揉,一...
    開(kāi)封第一講書(shū)人閱讀 52,255評(píng)論 1 308
  • 那天剪侮,我揣著相機(jī)與錄音,去河邊找鬼洛退。 笑死瓣俯,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的兵怯。 我是一名探鬼主播彩匕,決...
    沈念sama閱讀 40,825評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼媒区!你這毒婦竟也來(lái)了驼仪?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,729評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤袜漩,失蹤者是張志新(化名)和其女友劉穎绪爸,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體宙攻,經(jīng)...
    沈念sama閱讀 46,271評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡奠货,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了座掘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片递惋。...
    茶點(diǎn)故事閱讀 40,498評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖雹顺,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情廊遍,我是刑警寧澤嬉愧,帶...
    沈念sama閱讀 36,183評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站喉前,受9級(jí)特大地震影響没酣,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜卵迂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評(píng)論 3 333
  • 文/蒙蒙 一裕便、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧见咒,春花似錦偿衰、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,338評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)缤言。三九已至,卻和暖如春视事,著一層夾襖步出監(jiān)牢的瞬間胆萧,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,458評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工俐东, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留跌穗,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,906評(píng)論 3 376
  • 正文 我出身青樓虏辫,卻偏偏與公主長(zhǎng)得像蚌吸,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子乒裆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容