這個星期最開始 ,老大扔了2個任務過來,這個是其中之一。下面直接說步驟:
1. 查閱微信開發文檔
https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html
我將兩個重要的地方列出來
a 登錄流程時序圖,及說明
登錄流程時序
說明:
- 調用 wx.login() 獲取 臨時登錄憑證code ,並回傳到開發者服務器。
- 調用 auth.code2Session 接口,換取 用戶唯一標識 OpenID 和 會話密鑰 session_key。
之后開發者服務器可以根據用戶標識來生成自定義登錄態,用於后續業務邏輯中前后端交互時識別用戶身份。
注意:
- 會話密鑰
session_key
是對用戶數據進行 加密簽名 的密鑰。為了應用自身的數據安全,開發者服務器不應該把會話密鑰下發到小程序,也不應該對外提供這個密鑰。 - 臨時登錄憑證 code 只能使用一次
b. auth.code2Session 的文檔說明
auth.code2Session
本接口應在服務器端調用,詳細說明參見服務端API。
登錄憑證校驗。通過 wx.login 接口獲得臨時登錄憑證 code 后傳到開發者服務器調用此接口完成登錄流程。更多使用方法詳見 小程序登錄。
請求地址
GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
請求參數
屬性 | 類型 | 默認值 | 必填 | 說明 |
---|---|---|---|---|
appid | string | 是 | 小程序 appId | |
secret | string | 是 | 小程序 appSecret | |
js_code | string | 是 | 登錄時獲取的 code | |
grant_type | string | 是 | 授權類型,此處只需填寫 authorization_code |
返回值
Object
返回的 JSON 數據包
屬性 | 類型 | 說明 |
---|---|---|
openid | string | 用戶唯一標識 |
session_key | string | 會話密鑰 |
unionid | string | 用戶在開放平台的唯一標識符,在滿足 UnionID 下發條件的情況下會返回,詳見UnionID 機制說明。 |
errcode | number | 錯誤碼 |
errmsg | string | 錯誤信息 |
errcode 的合法值
值 | 說明 | 最低版本 |
---|---|---|
-1 | 系統繁忙,此時請開發者稍候再試 | |
0 | 請求成功 | |
40029 | code 無效 | |
45011 | 頻率限制,每個用戶每分鍾100次 |
2. WebAPI 實現代碼:主要包含三部分
第一部分:建立處理傳入參數和返回參數的Model
微信小程序傳入參數Model
public class WeXinLoginInModel { /// <summary> /// 小程序appid /// </summary> public string AppId { get; set; } /// <summary> /// 小程序appSecret /// </summary> public string AppSecret { get; set; } /// <summary> /// 小程序code /// </summary> public string Code { get; set; } }
小程序所需返回參數Model
public class WeXinLoginResultModel { /// <summary> /// 用戶唯一標識 /// </summary> public string OpenId { get; set; } /// <summary> /// 會話密鑰 /// </summary> public string Session_Key { get; set; } /// <summary> /// 用戶在開放平台的唯一標識符,在滿足 UnionID 下發條件的情況下會返回,詳見UnionID 機制說明。 /// </summary> public string Unionid { get; set; } /// <summary> /// 錯誤碼 /// </summary> public int ErrCode { get; set; } /// <summary> /// 錯誤信息 /// </summary> public string ErrMsg { get; set; } /// <summary> /// Redis里面OpenId值所對應的鍵OpenIdKey /// </summary> public string OpenIdKey { get; set; } /// <summary> /// Redis里面Session_Key值所對應的鍵SessionKey /// </summary> public string SessionKey { get; set; } }
第二部分:WebAPI里面寫方法,
調用 auth.code2Session里面的請求地址,然后將返回結果中的OpenId、Session_Key以鍵值對的形式存儲起來,而且將鍵名稱相關的信息返回給微信端。
[HttpGet("~/api/WeiXinLogin", Name = "WeiXinLogin")] public async Task<IActionResult> WeiXinLogin(string js_code) { WeXinLoginInModel weixin = new WeXinLoginInModel(); weixin.AppId = "wx30a387595dafb442"; //固定值,請參照小程序參數說明 weixin.AppSecret = "4e24cab02422082b11a406595dacee76";///固定值,請參照小程序參數說明 weixin.Code = js_code; //不固定 string param = $"?appid={weixin.AppId}&secret={weixin.AppSecret}&js_code={weixin.Code}&grant_type=authorization_code"; ; string url = "https://api.weixin.qq.com/sns/jscode2session"+param; var handler = new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip }; using (var http = new HttpClient(handler)) { //await異步等待回應 var response = await http.GetAsync(url); //確保HTTP成功狀態值 response.EnsureSuccessStatusCode(); var a= response.StatusCode; //await異步讀取最后的JSON(注意此時gzip已經被自動解壓縮了,因為上面的AutomaticDecompression = DecompressionMethods.GZip) string responseContent= await response.Content.ReadAsStringAsync(); var resultModel= JsonConvert.DeserializeObject<WeXinLoginResultModel>(responseContent); if(!string.IsNullOrEmpty(resultModel.OpenId) && !string.IsNullOrEmpty(resultModel.Session_Key)) { //將openid,session_key存入到Redis緩存中; string openIdKey = "openIdKey_" + Guid.NewGuid().ToString(); string sessionKey = "sessionKey_" + Guid.NewGuid().ToString(); _redisCacheManager.Set(openIdKey, resultModel.OpenId, TimeSpan.FromDays(1)); _redisCacheManager.Set(sessionKey, resultModel.Session_Key, TimeSpan.FromDays(1)); resultModel.OpenIdKey = openIdKey; resultModel.SessionKey = sessionKey; } //返回結果 return Ok(resultModel); } }
第三部分:微信端將鍵名稱存入storage值,
方便下次發起業務請求時帶上這個Storage值,去后端驗證OpenId、Session_Key是否有值,若有值,返回業務數據。
公司老大說他用Token, 后面我沒做了,過程省略。現提供后續思路如下:Storage值里面取出openIdKey、SessionKey——Redis 緩存里面根據openIdKey、SessionKey 取出openId、Session_Key——如果openId、Session_Key里面有值,說明該用戶前面登錄過,有權進行接下來的業務操作