H5及web頁面微信授權(quán)登錄流程

PC端微信掃碼登錄流程:

為什么要微信登錄:

如果用戶在微信客戶端中訪問第三方網(wǎng)頁蠢挡,公眾號可以通過微信網(wǎng)頁授權(quán)機(jī)制逊脯,來獲取用戶基本信息,進(jìn)而實現(xiàn)業(yè)務(wù)邏輯置谦。微信擁有龐大且穩(wěn)定活躍的用戶基數(shù)放坏,直接將我們的app接入到微信的生態(tài)可以免去復(fù)雜的新用戶注冊流程咙咽,使用戶體驗更良好。

微信登錄的幾種情況:
  • PC端:

    • PC端微信瀏覽器 -> 直接調(diào)用微信授權(quán)(不掃碼淤年,使用微信服務(wù)號的appid和appsecret)

    • PC端其他瀏覽器 -> 跳轉(zhuǎn)微信的掃碼登錄頁面(需要掃碼钧敞,使用微信開放平臺注冊的PC應(yīng)用appid和appsecret)

  • 移動端:

    • 微信客戶端打開 -> 直接調(diào)用微信授權(quán)(不掃碼,使用微信服務(wù)號的appid和appsecret)

    • 其他手機(jī)瀏覽器打開 -> 跳轉(zhuǎn)微信的掃碼登錄頁面(需要掃碼互亮,使用微信開放平臺注冊的PC應(yīng)用appid和appsecret)

區(qū)分是否是PC環(huán)境的方法:

判斷是PC環(huán)境還是移動環(huán)境是為了相應(yīng)切換應(yīng)用的布局犁享,目前采用css媒體查詢來做判斷:

/* 屏幕寬度小于等于1070像素時識別為移動端(1070像素是使推薦頁常用情報站欄不現(xiàn)實滾動條的最小寬度) */
@media screen and (max-width: 1070px) {
    /* 移動端布局css樣式 */
}
/* 屏幕寬度大于1071像素識別為PC端 */
@media screen and (min-width: 1071px) {
    /* PC端布局樣式 */
}

這里目前的設(shè)計是將判斷UI樣式和判斷登錄邏輯區(qū)分開的,兩個功能分別獨(dú)立判斷

區(qū)分微信登錄的幾種情況的方法:
  • 前端在登錄時獲取用戶設(shè)備信息(userAgent)
let UA = navigator.userAgent.toLocaleLowerCase()  
// UA的格式可能因設(shè)備不同而采用不同的大小寫格式這里我們先統(tǒng)一為小寫方便下一步判斷
UA.indexOf("micromessenger") != -1
// 通過indexOf方法來判斷字符串里是否有要查詢的字段

前端操作

1 獲取code(此步驟由前端完成)
  • 首先要在微信開放平臺里申請創(chuàng)建一個web應(yīng)用豹休,填寫完基本信息之后提交審核炊昆,最長7個工作日,一般兩天就能下來威根。審核通過以后可以得到web應(yīng)用的AppID和AppSecret凤巨,稍后請求微信登錄的二維碼。

  • 在得到web應(yīng)用的AppID以后前端需要配置請求登錄二維碼的url:

// 前端使用appid和回調(diào)域名來獲取微信登陸二維碼

window.location.replace(
    "https://open.weixin.qq.com/connect/qrconnect?" +
    "appid=" + APP_id + "&" +
    "redirect_uri=" + encodeURIComponent('http://wx.digitwonder.com') + "&" +
    "scope=snsapi_login#wechat_redirect" )

這個配置中AppID字段是向后臺傳微信開放平臺的web應(yīng)用AppID洛搀,回調(diào)地址也是在開放平臺注冊時留的地址敢茁,而且這個回調(diào)地址的uri需要經(jīng)過encode編碼加密以后拼接到請求的。'scope'字段表示請求的作用域留美,微信掃碼登錄時scope字段固定寫'snsapi_login'彰檬。將這個地址拼接好以后就可以將路由定向到微信的二維碼頁面了。

參數(shù)說明
參數(shù) 是否必須 說明
appid 應(yīng)用唯一標(biāo)識(前面認(rèn)證網(wǎng)頁應(yīng)用中獲得)
redirect_uri 重定向地址谎砾,需要進(jìn)行UrlEncode(前面認(rèn)證網(wǎng)頁應(yīng)用中獲得)
response_type 填code
scope 應(yīng)用授權(quán)作用域逢倍,擁有多個作用域用逗號(,)分隔,網(wǎng)頁應(yīng)用目前僅填寫snsapi_login即可
state 用于保持請求和回調(diào)的狀態(tài)景图,授權(quán)請求后原樣帶回給第三方较雕。該參數(shù)可用于防止csrf攻擊(跨站請求偽造攻擊),建議第三方帶上該參數(shù)挚币,可設(shè)置為簡單的隨機(jī)數(shù)加session進(jìn)行校驗
  • 在頁面定位到微信二維碼頁面以后掃碼確認(rèn)亮蒋,頁面會被定向到之前配置的回調(diào)頁面地址并且將請求來的code拼接到url上一并返回,我們在微信確認(rèn)登陸以后回到url拼接有code的頁面獲取到code之后向后臺發(fā)送登陸請求妆毕。
// 聲明變量flag用來存儲微信回調(diào)頁面的code信息
let flag = flag.split("&")[0];
// 重定向該頁面的路由(清除url中的code) - 避免發(fā)送code請求
this.$router.replace({
  path: "/login",
  query: {
    redirect: this.$route.query.redirect
  }
});

this.request({
        url: "/biz/login/wx",  // 后臺接收code的接口
        method: "POST",  // 使用HTTP的POST方法傳回code
        data: {
          code: flag  // 將頁面存儲code的flag變量以code字段傳給后臺
          // 此處區(qū)分登錄方式的字段待定
        }
      }).then(res => {
        // 前端本地獲取用戶信息后的方法
      })

后端操作

接口結(jié)構(gòu)

接口: (post)/biz/login/wx
參數(shù): browser(取值為 wx,other)
返回數(shù)據(jù)(json):

// 登錄成功時返回
{
    "code": 1,
    "msg": "SUCCESS",
    "data": {
        "nick": "用戶昵稱",
        "role_id": 2,
        "mobile": "手機(jī)號",
        "avatar": "用戶頭像",
        "birthday": 1578909982972,
        "gender": 2,
        "location": "地區(qū)",
        "summary": "用戶簡介",
        "eval": true,
        "status": "Complete",
        "last_login": 1578909982972,
        "id": "id",
        "create_time": 1571755690000,
        "update_time": 1578885503000
    }
}

// 登錄失敗時返回
{
    "code": 0,
    "msg": "FAILURE"
}
1 獲取access_token

收到登錄請求后首先通過code向微信服務(wù)器換取access_token慎玖。
根據(jù)不同的瀏覽器類型使用相應(yīng)的appid和secret

// 請求url(Get)
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
參數(shù)說明
參數(shù) 是否必須 說明
appid 應(yīng)用唯一標(biāo)識
secret 應(yīng)用密鑰AppSecret
code 填寫第一步獲取的code參數(shù)
grant_type 填authorization_code

微信瀏覽器登錄時使用公眾號appid和secret, 其他瀏覽器登錄使用網(wǎng)站應(yīng)用appid和secret

返回數(shù)據(jù)說明
名稱 類型 說明
access_token String access_token
expires_in int access_token有效時間
refresh_token String refresh_token
openid String open_id
scope String 授權(quán)作用域

當(dāng)獲取數(shù)據(jù)出錯時,返回結(jié)果中包含"errCode"字段, 登錄失敗

2 拉取用戶信息

通過第一步中獲取到的access_token和openid拉取user_info

// 請求url(Get)
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
參數(shù)說明
參數(shù) 是否必須 說明
access_token 上一步中獲取到的access_token
openid 微信用戶唯一標(biāo)識,上一步中獲取到的openid
返回數(shù)據(jù)說明
名稱 類型 說明
openid String open_id
unionid String union_id
nickname String 用戶昵稱
sex int 性別
province String
city String 城市
country String 國家
headimgurl String 用戶頭像
privilege Array 用戶權(quán)限

當(dāng)獲取數(shù)據(jù)出錯時,返回結(jié)果中包含"errCode"字段, 登錄失敗

3 生成或獲取本地用戶
  • 通過union_id獲取第三方平臺賬號
  • 第三方平臺賬號存在時通過uid獲取用戶數(shù)據(jù),否則繼續(xù)
  • 使用微信登錄的賬戶需要將其用戶數(shù)據(jù)轉(zhuǎn)換成本地用戶并存儲
  • 添加用戶緩存
  • 創(chuàng)建或更新用戶Auth數(shù)據(jù)
  • 更新ES(UserIndex)
  • 創(chuàng)建用戶媒體
4 返回用戶數(shù)據(jù)

將用戶數(shù)據(jù)返回到前臺

時序圖

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末笛粘,一起剝皮案震驚了整個濱河市凄吏,隨后出現(xiàn)的幾起案子远舅,更是在濱河造成了極大的恐慌,老刑警劉巖痕钢,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異序六,居然都是意外死亡任连,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進(jìn)店門例诀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來随抠,“玉大人,你說我怎么就攤上這事繁涂」八” “怎么了?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵扔罪,是天一觀的道長秉沼。 經(jīng)常有香客問我,道長矿酵,這世上最難降的妖魔是什么唬复? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮全肮,結(jié)果婚禮上敞咧,老公的妹妹穿的比我還像新娘。我一直安慰自己辜腺,他們只是感情好休建,可當(dāng)我...
    茶點故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著评疗,像睡著了一般测砂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上壤巷,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天邑彪,我揣著相機(jī)與錄音,去河邊找鬼胧华。 笑死寄症,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的矩动。 我是一名探鬼主播有巧,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼悲没!你這毒婦竟也來了篮迎?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎甜橱,沒想到半個月后逊笆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡岂傲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年难裆,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片镊掖。...
    茶點故事閱讀 38,673評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡乃戈,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出亩进,到底是詐尸還是另有隱情症虑,我是刑警寧澤,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布归薛,位于F島的核電站谍憔,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏苟翻。R本人自食惡果不足惜韵卤,卻給世界環(huán)境...
    茶點故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望崇猫。 院中可真熱鬧沈条,春花似錦、人聲如沸诅炉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涕烧。三九已至月而,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間议纯,已是汗流浹背父款。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留瞻凤,地道東北人憨攒。 一個月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像阀参,于是被迫代替她去往敵國和親肝集。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,562評論 2 349

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