日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

手把手教會(huì)你小程序登錄鑒權(quán)

導(dǎo)語

為了方便小程序應(yīng)用使用微信登錄態(tài)進(jìn)行授權(quán)登錄,微信小程序提供了登錄授權(quán)的開放接口。乍一看文檔,感覺文檔上講的非常有道理,但是實(shí)現(xiàn)起來又真的是摸不著頭腦,不知道如何管理和維護(hù)登錄態(tài)。本文就來手把手的教會(huì)大家在業(yè)務(wù)里如何接入和維護(hù)微信登錄態(tài)。

接入流程

這里官方文檔上的流程圖已經(jīng)足夠清晰,我們直接就該圖展開詳述和補(bǔ)充。

 

手把手教會(huì)你小程序登錄鑒權(quán)

 

 

首先大家看到這張圖,肯定會(huì)注意到小程序進(jìn)行通信交互的不止是小程序前端和我們自己的服務(wù)端,微信第三方服務(wù)端也參與其中,那么微信服務(wù)端在其中扮演著怎樣的角色呢?我們一起來串一遍登錄鑒權(quán)的流程就明白了。

1. 調(diào)用wx.login生成code

wx.login()這個(gè)API的作用就是為當(dāng)前用戶生成一個(gè)臨時(shí)的登錄憑證,這個(gè)臨時(shí)登錄憑證的有效期只有五分鐘。我們拿到這個(gè)登錄憑證后就可以進(jìn)行下一步操作:獲取openid和session_key

wx.login({
    success: function(loginRes) {
        if (loginRes.code) {
            // example: 081LXytJ1Xq1Y40sg3uJ1FWntJ1LXyth
        }
    }
});

復(fù)制代碼

2. 獲取openid和session_key

我們先來介紹下openid,用過公眾號(hào)的童鞋應(yīng)該對(duì)這個(gè)標(biāo)識(shí)都不陌生了,在公眾平臺(tái)里,用來標(biāo)識(shí)每個(gè)用戶在訂閱號(hào)、服務(wù)號(hào)、小程序這三種不同應(yīng)用的唯一標(biāo)識(shí),也就是說每個(gè)用戶在每個(gè)應(yīng)用的openid都是不一致的,所以在小程序里,我們可以用openid來標(biāo)識(shí)用戶的唯一性。

那么session_key是用來干嘛的呢?有了用戶標(biāo)識(shí),我們就需要讓該用戶進(jìn)行登錄,那么session_key就保證了當(dāng)前用戶進(jìn)行會(huì)話操作的有效性,這個(gè)session_key是微信服務(wù)端給我們派發(fā)的。也就是說,我們可以用這個(gè)標(biāo)識(shí)來間接地維護(hù)我們小程序用戶的登錄態(tài),那么這個(gè)session_key是怎么拿到的呢?我們需要在自己的服務(wù)端請(qǐng)求微信提供的第三方接口https://api.weixin.qq.com/sns/jscode2session,這個(gè)接口需要帶上四個(gè)參數(shù)字段:

參數(shù)值A(chǔ)ppid小程序的appidsecret小程序的secretjs_code前面調(diào)用wx.login派發(fā)的codegrant_type'authorization_code'

從這幾個(gè)參數(shù),我們可以看出,要請(qǐng)求這個(gè)接口必須先調(diào)用wx.login()來獲取到用戶當(dāng)前會(huì)話的code。那么為什么我們要在服務(wù)端來請(qǐng)求這個(gè)接口呢?其實(shí)是出于安全性的考量,如果我們?cè)谇岸送ㄟ^request調(diào)用此接口,就不可避免的需要將我們小程序的appid和小程序的secret暴露在外部,同時(shí)也將微信服務(wù)端下發(fā)的session_key暴露給“有心之人”,這就給我們的業(yè)務(wù)安全帶來極大的風(fēng)險(xiǎn)。除了需要在服務(wù)端進(jìn)行session_key的獲取,我們還需要注意兩點(diǎn):

  • session_key和微信派發(fā)的code是一一對(duì)應(yīng)的,同一code只能換取一次session_key。每次調(diào)用wx.login(),都會(huì)下發(fā)一個(gè)新的code和對(duì)應(yīng)的session_key,為了保證用戶體驗(yàn)和登錄態(tài)的有效性,開發(fā)者需要清楚用戶需要重新登錄時(shí)才去調(diào)用wx.login()
  • session_key是有時(shí)效性的,即便是不調(diào)用wx.login,session_key也會(huì)過期,過期時(shí)間跟用戶使用小程序的頻率成正相關(guān),但具體的時(shí)間長短開發(fā)者和用戶都是獲取不到的
function getSessionKey (code, appid, appSecret) {
    var opt = {
        method: 'GET',
        url: 'https://api.weixin.qq.com/sns/jscode2session',
        params: {
            appid: appid,
            secret: appSecret,
            js_code: code,
            grant_type: 'authorization_code'
        }
    };
    return http(opt).then(function (response) {
        var data = response.data;
        if (!data.openid || !data.session_key || data.errcode) {
            return {
                result: -2,
                errmsg: data.errmsg || '返回?cái)?shù)據(jù)字段不完整'
            }
        } else {
            return data
        }
    });
}
復(fù)制代碼

3. 生成3rd_session

前面說過通過session_key來“間接”地維護(hù)登錄態(tài),所謂間接,也就是我們需要自己維護(hù)用戶的登錄態(tài)信息,這里也是考慮到安全性因素,如果直接使用微信服務(wù)端派發(fā)的session_key來作為業(yè)務(wù)方的登錄態(tài)使用,會(huì)被“有心之人”用來獲取用戶的敏感信息,比如wx.getUserInfo()這個(gè)接口呢,就需要session_key來配合解密微信用戶的敏感信息。

那么我們?nèi)绻勺约旱牡卿洃B(tài)標(biāo)識(shí)呢,這里可以使用幾種常見的不可逆的哈希算法,比如md5、sha1等,將生成后的登錄態(tài)標(biāo)識(shí)(這里我們統(tǒng)稱為'skey')返回給前端,并在前端維護(hù)這份登錄態(tài)標(biāo)識(shí)(一般是存入storage)。而在服務(wù)端呢,我們會(huì)把生成的skey存在用戶對(duì)應(yīng)的數(shù)據(jù)表中,前端通過傳遞skey來存取用戶的信息。

可以看到這里我們使用了sha1算法來生成了一個(gè)skey:

const crypto = require('crypto');

return getSessionKey(code, appid, secret)
    .then(resData => {
        // 選擇加密算法生成自己的登錄態(tài)標(biāo)識(shí)
        const { session_key } = resData;
        const skey = encryptSha1(session_key);
    });
    
function encryptSha1(data) {
    return crypto.createHash('sha1').update(data, 'utf8').digest('hex')
}
復(fù)制代碼

4. checkSession

前面我們將skey存入前端的storage里,每次進(jìn)行用戶數(shù)據(jù)請(qǐng)求時(shí)會(huì)帶上skey,那么如果此時(shí)session_key過期呢?所以我們需要調(diào)用到wx.checkSession()這個(gè)API來校驗(yàn)當(dāng)前session_key是否已經(jīng)過期,這個(gè)API并不需要傳入任何有關(guān)session_key的信息參數(shù),而是微信小程序自己去調(diào)自己的服務(wù)來查詢用戶最近一次生成的session_key是否過期。如果當(dāng)前session_key過期,就讓用戶來重新登錄,更新session_key,并將最新的skey存入用戶數(shù)據(jù)表中。

checkSession這個(gè)步驟呢,我們一般是放在小程序啟動(dòng)時(shí)就校驗(yàn)登錄態(tài)的邏輯處,這里貼個(gè)校驗(yàn)登錄態(tài)的流程圖:

 

手把手教會(huì)你小程序登錄鑒權(quán)

 

 

下面代碼即校驗(yàn)登錄態(tài)的簡單流程:

let loginFlag = wx.getStorageSync('skey');
if (loginFlag) {
    // 檢查 session_key 是否過期
    wx.checkSession({
        // session_key 有效(未過期)
        success: function() {
            // 業(yè)務(wù)邏輯處理
        },
    
        // session_key 過期
        fail: function() {
            // session_key過期,重新登錄
            doLogin();
        }
    });
) else {
    // 無skey,作為首次登錄
    doLogin();
}
復(fù)制代碼

5. 支持emoji表情存儲(chǔ)

如果需要將用戶微信名存入數(shù)據(jù)表中,那么就確認(rèn)數(shù)據(jù)表及數(shù)據(jù)列的編碼格式。因?yàn)橛脩粑⑿琶赡軙?huì)包含emoji圖標(biāo),而常用的UTF8編碼只支持1-3個(gè)字節(jié),emoji圖標(biāo)剛好是4個(gè)字節(jié)的編碼進(jìn)行存儲(chǔ)。

這里有兩種方式(以MySQL為例):

1.設(shè)置存儲(chǔ)字符集

在mysql5.5.3版本后,支持將數(shù)據(jù)庫及數(shù)據(jù)表和數(shù)據(jù)列的字符集設(shè)置為utf8mb4,因此可在/etc/my.cnf設(shè)置默認(rèn)字符集編碼及服務(wù)端編碼格式

// my.cnf

[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
[mysqld]
character-set-client-handshake = FALSE
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
復(fù)制代碼

設(shè)置完默認(rèn)字符集編碼及服務(wù)端字符集編碼,如果是對(duì)已經(jīng)存在的表和字段進(jìn)行編碼轉(zhuǎn)換,需要執(zhí)行下面幾個(gè)步驟:

  • 設(shè)置數(shù)據(jù)庫字符集為utf8mb4
ALTER DATABASE 數(shù)據(jù)庫名稱 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

復(fù)制代碼
  • 設(shè)置數(shù)據(jù)表字符集為utf8mb4
ALTER TABLE 數(shù)據(jù)表名稱 CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

復(fù)制代碼
  • 設(shè)置數(shù)據(jù)列字段字符集為utf8mb4
ALTER TABLE 數(shù)據(jù)表名稱 CHANGE 字段列名稱 VARCHAR(n) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

復(fù)制代碼

這里的COLLATE指的是排序字符集,也就是用來對(duì)存儲(chǔ)的字符進(jìn)行排序和比較的,utf8mb4常用的collation有兩種:utf8mb4_unicode_ci和utf8mb4_general_ci,一般建議使用utf8mb4_unicode_ci,因?yàn)樗腔跇?biāo)準(zhǔn)的Unicode Collation Algorithm(UCA)來排序的,可以在各種語言進(jìn)行精確排序。這兩種排序方式的具體區(qū)別可以參考:What's the difference between utf8_general_ci and utf8_unicode_ci

  1. 通過使用sequelize對(duì)emoji字符進(jìn)行編碼入庫,使用時(shí)再進(jìn)行解碼

這里是sequelize的配置,可參考Sequelize文檔

{
       dialect: 'mysql',    // 數(shù)據(jù)庫類型
       dialectOptions: {    
         charset: 'utf8mb4',
         collate: "utf8mb4_unicode_ci"
      },
}
復(fù)制代碼

最后

前面講了微信小程序如何接入微信登錄態(tài)標(biāo)識(shí)的詳細(xì)流程,那么如何獲取小程序中的用戶數(shù)據(jù)以及對(duì)用戶敏感數(shù)據(jù)進(jìn)行解密,并保證用戶數(shù)據(jù)的完整性,我將在下一篇文章給大家做一個(gè)詳細(xì)地介紹。

分享到:
標(biāo)簽:程序
用戶無頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績?cè)u(píng)定