小程序模板網(wǎng)

小程序的登陸和授權(quán)

發(fā)布時間:2020-05-20 10:00 所屬欄目:小程序開發(fā)教程

1.小程序登錄

登入官方說明

小程序可以通過微信官方提供的登錄能力方便地獲取微信提供的用戶身份標識,快速建立小程序內(nèi)的用戶體系。

登錄流程時序

說明:

  1. 調(diào)用 wx.login() 獲取 臨時登錄憑證code ,并回傳到開發(fā)者服務(wù)器。
  2. 調(diào)用 code2Session 接口,換取 用戶唯一標識 OpenID 和 會話密鑰 session_key 。

之后開發(fā)者服務(wù)器可以根據(jù)用戶標識來生成自定義登錄態(tài),用于后續(xù)業(yè)務(wù)邏輯中前后端交互時識別用戶身份。

注意:

  1. 會話密鑰 session_key 是對用戶數(shù)據(jù)進行 加密簽名 的密鑰。為了應用自身的數(shù)據(jù)安全,開發(fā)者服務(wù)器 不應該把會話密鑰下發(fā)到小程序,也不應該對外提供這個密鑰 。
  2. 臨時登錄憑證 code 只能使用一次

兄弟們,是不是很簡單,一看就會?我知道你們的回答如下圖,但是不要慌,我們詳細講每一步

小程序端執(zhí)行wx.login后在回調(diào)函數(shù)中就能拿到上圖的code,然后把這個code傳給我們后端程序,后端拿到這個這個code后,可以請求code2Session接口拿到用的openid和session_key,openid是用戶在微信中唯一標識,我們就可以把這個兩個值(val)存起來,然后返回一個鍵(key)給小程序端,下次小程序請求我們后端的時候,帶上這個key,我們就能找到這個val,就可以,這樣就把登入做好了。

1.1wx.login(Object object)

調(diào)用接口獲取登錄憑證(code)。通過憑證進而換取用戶登錄態(tài)信息,包括用戶的唯一標識(openid)及本次登錄的會話密鑰(session_key)等。用戶數(shù)據(jù)的加解密通訊需要依賴會話密鑰完成。更多使用方法詳見 小程序登錄 。

參數(shù)

Object object

屬性 類型 默認值 必填 說明 最低版本
timeout number   超時時間,單位ms 1.9.90
success function   接口調(diào)用成功的回調(diào)函數(shù)  
fail function   接口調(diào)用失敗的回調(diào)函數(shù)  
complete function   接口調(diào)用結(jié)束的回調(diào)函數(shù)(調(diào)用成功、失敗都會執(zhí)行)  

object.success 回調(diào)函數(shù)

參數(shù)

Object res

屬性 類型 說明
code string 用戶登錄憑證(有效期五分鐘)。開發(fā)者需要在開發(fā)者服務(wù)器后臺調(diào)用 code2Session ,使用 code 換取 openid 和 session_key 等信息

示例代碼

wx.login({
  success(res) {
    if (res.code) {
      // 發(fā)起網(wǎng)絡(luò)請求
      wx.request({
        url: 'https://test.com/onLogin',
        data: {
          code: res.code
        },
        success: function (res) {
              wx.setStorageSync('login_key', res.data.data.login_key);
        }
      })
    } else {
      console.log('登錄失??!' + res.errMsg)
    }
  }
})

1.2code2Session

本接口應在服務(wù)器端調(diào)用,詳細說明參見 服務(wù)端API 。

登錄憑證校驗。通過 wx.login() 接口獲得臨時登錄憑證 code 后傳到開發(fā)者服務(wù)器調(diào)用此接口完成登錄流程。更多使用方法詳見 小程序登錄 。

請求地址

GET https://api.weixin.qq.com/sns/jscode2sessionappid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code

請求參數(shù)

屬性 類型 默認值 必填 說明
appid string   小程序 appId
secret string   小程序 appSecret
js_code string   登錄時獲取的 code
grant_type string   授權(quán)類型,此處只需填寫 authorization_code

返回值

Object

返回的 JSON 數(shù)據(jù)包

屬性 類型 說明
openid string 用戶唯一標識
session_key string 會話密鑰
unionid string 用戶在開放平臺的唯一標識符,在滿足 UnionID 下發(fā)條件的情況下會返回,詳見 UnionID 機制說明 。
errcode number 錯誤碼
errmsg string 錯誤信息

errcode 的合法值

說明
-1 系統(tǒng)繁忙,此時請開發(fā)者稍候再試
0 請求成功
40029 code 無效
45011 頻率限制,每個用戶每分鐘100次

說完上面的登入后,我們是不是還沒有用到上面的session_key?這個就是在用戶授權(quán)的時候用的,用來解密用戶的數(shù)據(jù),還要解密?是的你沒有聽錯,不要慌,下面給你解釋

2.微信授權(quán)獲取用戶信

后端獲取微信用戶信息流程

微信官方:忘了告訴你,session_key還會過期的,是的,沒錯就是這樣坑爹。

我的回復:我就是頭鐵,我不管session_key過期,會帶來什么樣的后果呢?

微信官方:對不起,你頭鐵沒有,你后端程序無法用戶授權(quán)的數(shù)據(jù),就問你氣不氣?

我的回復:好的,你牛逼,我可以接收你session_key過期,但是你要告訴我怎么判斷他是過期的吧?怎么獲取新的session_key吧?

微信官方:還是要按照我的要求來吧?看你這么可憐,告訴你吧,用wx.checkSession判斷是否過期,如果過期就重寫登入吧!獲取新的code,后端在去請求code2Session獲取新的session_key

我的回復:好的,謝謝你sb

判斷session_key有沒有過期

2.1wx.checkSession(Object object)

檢查登錄態(tài)是否過期。

通過 wx.login 接口獲得的用戶登錄態(tài)擁有一定的時效性。用戶越久未使用小程序,用戶登錄態(tài)越有可能失效。反之如果用戶一直在使用小程序,則用戶登錄態(tài)一直保持有效。具體時效邏輯由微信維護,對開發(fā)者透明。開發(fā)者只需要調(diào)用 wx.checkSession 接口檢測當前用戶登錄態(tài)是否有效。

登錄態(tài)過期后開發(fā)者可以再調(diào)用 wx.login 獲取新的用戶登錄態(tài)。調(diào)用成功說明當前 session_key 未過期,調(diào)用失敗說明 session_key 已過期。更多使用方法詳見 小程序登錄 。

參數(shù)

Object object

屬性 類型 默認值 必填 說明
success function   接口調(diào)用成功的回調(diào)函數(shù)
fail function   接口調(diào)用失敗的回調(diào)函數(shù)
complete function   接口調(diào)用結(jié)束的回調(diào)函數(shù)(調(diào)用成功、失敗都會執(zhí)行)

示例代碼

wx.checkSession({
  success() {
    // session_key 未過期,并且在本生命周期一直有效
  },
  fail() {
    // session_key 已經(jīng)失效,需要重新執(zhí)行登錄流程
    wx.login() // 重新登錄
  }
})

微信官方:你要獲取用的信息?我告訴你哈,如果要獲取的話,要經(jīng)過用戶同意的。

我的回復:sb,我怎么知道他是否授權(quán)過呢?如果沒有授權(quán),我怎么讓他授權(quán)?

**微信官方:你好,你可以調(diào)用wx.getSetting來判斷,用戶是否授權(quán),如果沒有授權(quán),你要讓他點擊按鈕,調(diào)起授權(quán)頁面。用戶點擊同意授權(quán)以后*,你就可以調(diào)用wx.getUserInfo接口獲取數(shù)據(jù)了**

我的回復:媽的,怎么這么麻煩?

微信官方:對不起,大佬,沒有辦法啊,我們要保護用戶的信息安全啊

我的回復:哦

2.2wx.getSetting(Object object)

基礎(chǔ)庫 1.2.0 開始支持,低版本需做 兼容處理 。

獲取用戶的當前設(shè)置。 返回值中只會出現(xiàn)小程序已經(jīng)向用戶請求過的權(quán)限 。

參數(shù)

Object object

屬性 類型 默認值 必填 說明
success function   接口調(diào)用成功的回調(diào)函數(shù)
fail function   接口調(diào)用失敗的回調(diào)函數(shù)
complete function   接口調(diào)用結(jié)束的回調(diào)函數(shù)(調(diào)用成功、失敗都會執(zhí)行)

object.success 回調(diào)函數(shù)

參數(shù)

Object res

屬性 類型 說明
authSetting AuthSetting 用戶授權(quán)結(jié)果

示例代碼

wx.getSetting({
  success(res) {
    console.log(res.authSetting)
    //部分結(jié)果,如果為true,則表示該用戶對這項權(quán)限以及授權(quán),如果沒有授權(quán),我們這需要通過button按鈕讓用戶授權(quán)
    // res.authSetting = {
    //   "scope.userInfo": true,
    //   "scope.userLocation": true
    // }
  }
})

注意事項

  1. wx.authorize({scope: "scope.userInfo"}) ,不會彈出授權(quán)窗口,請使用 <button_open-type="getUserInfo">
  2. 需要授權(quán) scope.userLocation 時必須 配置地理位置用途說明 。

微信官方:當你小程序端調(diào)用我們wx.getUserInfo的時候,我們會返回你用的基本信息。

我的回復:什么是基本信息,哪些是敏感信息?我后端怎么獲取呢?

微信官方:比如openid這些,大佬,你又兩種方法,第一:你可以將這些基本信息傳到后端,第二: 你可以講getUserInfo中的 iv,encryptedData傳給后端解密,機密后就能獲取到用戶的敏感信息了

我的回復:好的,我后端怎么解密呢?用什么解密呢?

微信官方:你登入的時候不是,后端不是存了session_key嗎?加上這些數(shù)據(jù),就可以解密了

我的回復:哦

2.3wx.getUserInfo(Object object)

獲取用戶信息

調(diào)用前需要 用戶授權(quán) scope.userInfo。

獲取用戶信息。

參數(shù)

Object object

屬性 類型 默認值 必填 說明
withCredentials boolean   是否帶上登錄態(tài)信息。當 withCredentials 為 true 時,要求此前有調(diào)用過 wx.login 且登錄態(tài)尚未過期,此時返回的數(shù)據(jù)會包含 encryptedData, iv 等敏感信息;當 withCredentials 為 false 時,不要求有登錄態(tài),返回的數(shù)據(jù)不包含 encryptedData, iv 等敏感信息。
lang string en 顯示用戶信息的語言
success function   接口調(diào)用成功的回調(diào)函數(shù)
fail function   接口調(diào)用失敗的回調(diào)函數(shù)
complete function   接口調(diào)用結(jié)束的回調(diào)函數(shù)(調(diào)用成功、失敗都會執(zhí)行)

object.lang 的合法值

說明
en 英文
zh_CN 簡體中文
zh_TW 繁體中文

object.success 回調(diào)函數(shù)

參數(shù)

Object res

屬性 類型 說明
userInfo UserInfo 用戶信息對象,不包含 openid 等敏感信息
rawData string 不包括敏感信息的原始數(shù)據(jù)字符串,用于計算簽名
signature string 使用 sha1( rawData + sessionkey ) 得到字符串,用于校驗用戶信息,詳見 用戶數(shù)據(jù)的簽名驗證和加解密
encryptedData string 包括敏感數(shù)據(jù)在內(nèi)的完整用戶信息的加密數(shù)據(jù),詳見 用戶數(shù)據(jù)的簽名驗證和加解密
iv string 加密算法的初始向量,詳見 用戶數(shù)據(jù)的簽名驗證和加解密

接口調(diào)整說明

在用戶未授權(quán)過的情況下調(diào)用此接口,將不再出現(xiàn)授權(quán)彈窗,會直接進入 fail 回調(diào)(詳見 《公告》 )。在用戶已授權(quán)的情況下調(diào)用此接口,可成功獲取用戶信息。

示例代碼

// 必須是在用戶已經(jīng)授權(quán)的情況下調(diào)用
wx.getUserInfo({
  success(res) {
    const userInfo = res.userInfo
    const nickName = userInfo.nickName
    const avatarUrl = userInfo.avatarUrl
    const gender = userInfo.gender // 性別 0:未知、1:男、2:女
    const province = userInfo.province
    const city = userInfo.city
    const country = userInfo.country
  }
})

encryptedData 解密后為以下 json 結(jié)構(gòu),詳見 加密數(shù)據(jù)解密算法

{
  "openId": "OPENID",
  "nickName": "NICKNAME",
  "gender": GENDER,
  "city": "CITY",
  "province": "PROVINCE",
  "country": "COUNTRY",
  "avatarUrl": "AVATARURL",
  "unionId": "UNIONID",
  "watermark": {
    "appid": "APPID",
    "timestamp": TIMESTAMP
  }
}

示例代碼

<!-- 如果只是展示用戶頭像昵稱,可以使用 <open-data /> 組件 -->
<open-data type="userAvatarUrl"></open-data>
<open-data type="userNickName"></open-data>
<!-- 需要使用 button 來授權(quán)登錄 -->
<button
  wx:if="{{canIUse}}"
  open-type="getUserInfo"
  bindgetuserinfo="bindGetUserInfo"
>
  授權(quán)登錄
</button>
<view wx:else>請升級微信版本</view>

Page({
  data: {
    canIUse: wx.canIUse('button.open-type.getUserInfo')
  },
  onLoad() {
    // 查看是否授權(quán)
    wx.getSetting({
      success(res) {
        if (res.authSetting['scope.userInfo']) {
          // 已經(jīng)授權(quán),可以直接調(diào)用 getUserInfo 獲取頭像昵稱
          wx.getUserInfo({
            success(res) {
              console.log(res.userInfo)
               wx.request({
                  url: url,
                  data: {
                    'iv': res.iv,
                    'encryptedData': res.encryptedData,
                    'login_key':登入標識
                  },
                  method: "POST",
                  header: {
                    'content-type': 'application/json' // 默認值
                  },
                  success: function (res) {
                    //解密后數(shù)據(jù)
                    console.log(res);
                  }
                });
            }
          })
        }
      }
    })
  },
  bindGetUserInfo(e) {
    console.log(e.detail.userInfo)
  }
})

叫你解密大法

2.4開放數(shù)據(jù)校驗與解密

小程序可以通過各種前端接口獲取微信提供的開放數(shù)據(jù)。考慮到開發(fā)者服務(wù)器也需要獲取這些開放數(shù)據(jù),微信會對這些數(shù)據(jù)做簽名和加密處理。開發(fā)者后臺拿到開放數(shù)據(jù)后可以對數(shù)據(jù)進行校驗簽名和解密,來保證數(shù)據(jù)不被篡改。

簽名校驗以及數(shù)據(jù)加解密涉及用戶的會話密鑰 session_key。 開發(fā)者應該事先通過 wx.login 登錄流程獲取會話密鑰 session_key 并保存在服務(wù)器。為了數(shù)據(jù)不被篡改,開發(fā)者不應該把 session_key 傳到小程序客戶端等服務(wù)器外的環(huán)境。

數(shù)據(jù)簽名校驗

為了確保開放接口返回用戶數(shù)據(jù)的安全性,微信會對明文數(shù)據(jù)進行簽名。開發(fā)者可以根據(jù)業(yè)務(wù)需要對數(shù)據(jù)包進行簽名校驗,確保數(shù)據(jù)的完整性。

  1. 通過調(diào)用接口(如 wx.getUserInfo )獲取數(shù)據(jù)時,接口會同時返回 rawData、signature,其中 signature = sha1( rawData + session_key )
  2. 開發(fā)者將 signature、rawData 發(fā)送到開發(fā)者服務(wù)器進行校驗。服務(wù)器利用用戶對應的 session_key 使用相同的算法計算出簽名 signature2 ,比對 signature 與 signature2 即可校驗數(shù)據(jù)的完整性。

如 wx.getUserInfo的數(shù)據(jù)校驗:

接口返回的rawData:

{
  "nickName": "Band",
  "gender": 1,
  "language": "zh_CN",
  "city": "Guangzhou",
  "province": "Guangdong",
  "country": "CN",
  "avatarUrl": "http://wx.qlogo.cn/mmopen/vi_32/1vZvI39NWFQ9XM4LtQpFrQJ1xlgZxx3w7bQxKARol6503Iuswjjn6nIGBiaycAjAtpujxyzYsrztuuICqIM5ibXQ/0"
}

用戶的 session-key:

HyVFkGl5F5OQWJZZaNzBBg==

用于簽名的字符串為:

{"nickName":"Band","gender":1,"language":"zh_CN","city":"Guangzhou","province":"Guangdong","country":"CN","avatarUrl":"http://wx.qlogo.cn/mmopen/vi_32/1vZvI39NWFQ9XM4LtQpFrQJ1xlgZxx3w7bQxKARol6503Iuswjjn6nIGBiaycAjAtpujxyzYsrztuuICqIM5ibXQ/0"}HyVFkGl5F5OQWJZZaNzBBg==

使用sha1得到的結(jié)果為

75e81ceda165f4ffa64f4068af58c64b8f54b88c

加密數(shù)據(jù)解密算法

接口如果涉及敏感數(shù)據(jù)(如 wx.getUserInfo 當中的 openId 和 unionId),接口的明文內(nèi)容將不包含這些敏感數(shù)據(jù)。開發(fā)者如需要獲取敏感數(shù)據(jù),需要對接口返回的 加密數(shù)據(jù)(encryptedData) 進行對稱解密。 解密算法如下:

  1. 對稱解密使用的算法為 AES-128-CBC,數(shù)據(jù)采用PKCS#7填充。
  2. 對稱解密的目標密文為 Base64_Decode(encryptedData)。
  3. 對稱解密秘鑰 aeskey = Base64_Decode(session_key), aeskey 是16字節(jié)。
  4. 對稱解密算法初始向量 為Base64_Decode(iv),其中iv由數(shù)據(jù)接口返回。

微信官方提供了多種編程語言的示例代碼( 點擊下載 )。每種語言類型的接口名字均一致。調(diào)用方式可以參照示例。

另外,為了應用能校驗數(shù)據(jù)的有效性,會在敏感數(shù)據(jù)加上數(shù)據(jù)水印( watermark )

watermark參數(shù)說明:

參數(shù) 類型 說明
appid String 敏感數(shù)據(jù)歸屬 appId,開發(fā)者可校驗此參數(shù)與自身 appId 是否一致
timestamp Int 敏感數(shù)據(jù)獲取的時間戳, 開發(fā)者可以用于數(shù)據(jù)時效性校驗

如接口 wx.getUserInfo 敏感數(shù)據(jù)當中的 watermark:

{
  "openId": "OPENID",
  "nickName": "NICKNAME",
  "gender": GENDER,
  "city": "CITY",
  "province": "PROVINCE",
  "country": "COUNTRY",
  "avatarUrl": "AVATARURL",
  "unionId": "UNIONID",
  "watermark": {
    "appid": "APPID",
    "timestamp": TIMESTAMP
  }
}

注:

  1. 解密后得到的json數(shù)據(jù)根據(jù)需求可能會增加新的字段,舊字段不會改變和刪減,開發(fā)者需要預留足夠的空間

會話密鑰 session_key 有效性

開發(fā)者如果遇到因為 session_key 不正確而校驗簽名失敗或解密失敗,請關(guān)注下面幾個與 session_key 有關(guān)的注意事項。

  1. wx.login 調(diào)用時,用戶的 session_key 可能 會被更新而致使舊 session_key 失效(刷新機制存在最短周期,如果同一個用戶短時間內(nèi)多次調(diào)用 wx.login ,并非每次調(diào)用都導致 session_key 刷新)。開發(fā)者應該在明確需要重新登錄時才調(diào)用 wx.login ,及時通過 code2Session接口更新服務(wù)器存儲的 session_key。
  2. 微信不會把 session_key 的有效期告知開發(fā)者。我們會根據(jù)用戶使用小程序的行為對 session_key 進行續(xù)期。用戶越頻繁使用小程序,session_key 有效期越長。
  3. 開發(fā)者在 session_key 失效時,可以通過重新執(zhí)行登錄流程獲取有效的 session_key。使用接口 wx.checkSession 可以校驗 session_key 是否有效,從而避免小程序反復執(zhí)行登錄流程。
  4. 當開發(fā)者在實現(xiàn)自定義登錄態(tài)時,可以考慮以 session_key 有效期作為自身登錄態(tài)有效期,也可以實現(xiàn)自定義的時效性策略。
  5.  


易優(yōu)小程序(企業(yè)版)+靈活api+前后代碼開源 碼云倉庫:starfork
本文地址:http://22321a.com/wxmini/doc/course/25232.html 復制鏈接 如需定制請聯(lián)系易優(yōu)客服咨詢:800182392 點擊咨詢
QQ在線咨詢