微信pc掃碼登錄網(wǎng)頁(OAuth 2.0)前后端流程(基于nodejs)

短的答案

  1. 在微信開放平臺(tái)上注冊(cè)一個(gè)網(wǎng)頁應(yīng)用的賬號(hào), 審批通過之后會(huì)生成一個(gè) AppId 和 AppSecret
  2. 用戶在網(wǎng)頁上觸發(fā)登錄機(jī)制后, 瀏覽器會(huì)跳轉(zhuǎn)到一個(gè)拼湊出來的的 url 上
    例如, 在京東使用微信登錄, 它的 url 是這樣的
    https://open.weixin.qq.com/connect/qrconnect?appid=wx827225356b689e24&state=4254CD505A1F4E17DDD96009D4EA2BB860FC6C77A08C92FF3928F27AF381BB92C770127B30BC8487D1703C5878979B10&redirect_uri=https%3A%2F%2Fqq.jd.com%2Fnew%2Fwx%2Fcallback.action%3Fview%3Dnull%26uuid%3Def5652d6750f404399e62e4e7510b066&response_type=code&scope=snsapi_login#wechat_redirect](https://open.weixin.qq.com/connect/qrconnect?appid=wx827225356b689e24&state=4254CD505A1F4E17DDD96009D4EA2BB860FC6C77A08C92FF3928F27AF381BB92C770127B30BC8487D1703C5878979B10&redirect_uri=https%3A%2F%2Fqq.jd.com%2Fnew%2Fwx%2Fcallback.action%3Fview%3Dnull%26uuid%3Def5652d6750f404399e62e4e7510b066&response_type=code&scope=snsapi_login#wechat_redirect)
    觀察一下, 這個(gè) url 以 key1=value1&key2=value2 的形式攜帶了一些信息
    那么, 當(dāng)用戶跳轉(zhuǎn)到這個(gè) url 上時(shí), 這些信息就以查詢參數(shù)的形式發(fā)送給微信的服務(wù)器, 微信服務(wù)器會(huì)返回一個(gè)頁面, 用戶在掃描微信上的二維碼后, 微信服務(wù)器就會(huì)完成那那一部分的工作, 然后讓用戶端主動(dòng)跳轉(zhuǎn)到我們事先準(zhǔn)備的一個(gè) url 上, 例如 www.xxx.com/authcallback?code=xxxxxxx, 以查詢參數(shù)的形式攜帶一個(gè) code, 這樣我們自己的服務(wù)器就能拿到這個(gè) code
  3. 我們服務(wù)器后臺(tái)根據(jù)這個(gè) code 再去請(qǐng)求微信服務(wù)器, 他會(huì)返回 openid, unionid, userinfo 等信息, 我們的服務(wù)器用 redis 或者其他數(shù)據(jù)庫記錄下這個(gè)信息
  4. 用 cookie 或類似的手段來給頁面記錄一下身份, 以便下次用戶訪問的時(shí)候會(huì)找到這個(gè)用戶的 openid 等信息, 這樣就完成了一個(gè)第三方登錄的流程

長(zhǎng)的答案(完整代碼)

一. 前端跳轉(zhuǎn)到微信的url上

這里使用的是在當(dāng)前頁面掃碼登錄的方式 (如果想使用類似京東直接跳轉(zhuǎn)的登錄, 可以直接平湊出來一個(gè) url 然后跳轉(zhuǎn)即可 )

  1. 引入微信登錄的js文件
    <script src="https://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js"></script>
  2. 調(diào)用微信的接口
var obj = new WxLogin({
    id: "login_container",
    appid: "wx8725b9a19e0abc0e",
    scope: "snsapi_login",
    redirect_uri: "https://xxx.com/auth/callback",
    state: "",
    style: "",
    href: ""
})
  1. 幾個(gè)參數(shù)的含義
  • id: 顯示登錄二維碼的容器
  • appid: 網(wǎng)站應(yīng)用的id
  • scope: 網(wǎng)頁應(yīng)用只用寫 snsapi_login
  • redirect_uri: 后端準(zhǔn)備的回調(diào)地址, 用來接收code
  • state: 會(huì)原路返回, 可用于防止csrf攻擊, 非必須
  • style: 二維碼的樣式, 提供"black", "white", 非必需
  • href: 自定義樣式鏈接

二. 后端接收 code

后端使用的是 express 的寫法
同時(shí)也使用了由樸靈大神寫的庫 wechat-oauth, 它內(nèi)部封裝了獲取用戶信息的方法, 讓我們不必糾結(jié)于這些細(xì)節(jié)
只需要知道它做了什么: 發(fā)送 code 到微信的服務(wù)器, 然后微信返回了用戶的信息
可以命令行運(yùn)行 npm i wechat-oauth 下載
代碼如下

const OAuth = require('wechat-oauth')
const router = express.Router()
// 使用網(wǎng)頁應(yīng)用的 appid 和 secret 去初始化 wechat-oauth 的方法
const wxPcClient = new OAuth(WX_APP_ID, WX_APP_SECRET)
router.get('/callback', (req, res) => {
  // 這里接收前端的 redirect_url 傳遞的 code 
  const { code } = req.query 
  wxPcClient.getAccessToken(code, (err, result) => {
    if (!err) {
      const accessToken = result.data.access_token
      const openId = result.data.openid
      const unionId = result.data.unionid
      // 這里生成一個(gè) sessionid
      const sessionId = generateSessionId()
      wxPcClient.getUser(openId, (err, result) => {
        // 這里獲取到了用戶的信息, 可以存儲(chǔ)在數(shù)據(jù)庫中
        const {nickname, sex, city, province, country, headimgurl} = result
        // 設(shè)置一個(gè) cookie 用于標(biāo)記這個(gè)用戶
        res.cookie('wxsessionid', sessionId, { maxAge: 84600000, httpOnly: true })
        // 登錄成功后做一個(gè)跳轉(zhuǎn), 也可以不做
        res.redirect('https://xxx.com/yyy.html')
      })
    }
  })
})

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末擂错,一起剝皮案震驚了整個(gè)濱河市全封,隨后出現(xiàn)的幾起案子刹悴,更是在濱河造成了極大的恐慌,老刑警劉巖土匀,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件就轧,死亡現(xiàn)場(chǎng)離奇詭異妒御,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)乎莉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門哼鬓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人健盒,你說我怎么就攤上這事称簿。” “怎么了搏色?”我有些...
    開封第一講書人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)券册。 經(jīng)常有香客問我频轿,道長(zhǎng),這世上最難降的妖魔是什么烁焙? 我笑而不...
    開封第一講書人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任航邢,我火速辦了婚禮,結(jié)果婚禮上骄蝇,老公的妹妹穿的比我還像新娘膳殷。我一直安慰自己,他們只是感情好九火,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開白布赚窃。 她就那樣靜靜地躺著,像睡著了一般勒极。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上虑鼎,一...
    開封第一講書人閱讀 49,185評(píng)論 1 284
  • 那天辱匿,我揣著相機(jī)與錄音,去河邊找鬼炫彩。 笑死匾七,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的江兢。 我是一名探鬼主播昨忆,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼杉允!你這毒婦竟也來了邑贴?” 一聲冷哼從身側(cè)響起限府,我...
    開封第一講書人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎痢缎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體世澜,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡独旷,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了寥裂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嵌洼。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖封恰,靈堂內(nèi)的尸體忽然破棺而出麻养,到底是詐尸還是另有隱情,我是刑警寧澤诺舔,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布鳖昌,位于F島的核電站,受9級(jí)特大地震影響低飒,放射性物質(zhì)發(fā)生泄漏许昨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一褥赊、第九天 我趴在偏房一處隱蔽的房頂上張望糕档。 院中可真熱鬧,春花似錦拌喉、人聲如沸速那。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽端仰。三九已至,卻和暖如春残家,著一層夾襖步出監(jiān)牢的瞬間榆俺,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工坞淮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留茴晋,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓回窘,卻偏偏與公主長(zhǎng)得像诺擅,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子啡直,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

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