{"record":{"id":"39c64ce399cdfba6","repo":"JeffreySu/WeiXinMPSDK","slug":"sessionkey-encrypthelper","errorCode":null,"errorMessage":"SessionKey无效","messagePattern":"SessionKey无效","errorType":"exception","errorClass":"WxOpenException","httpStatus":null,"severity":"error","filePath":"src/Senparc.Weixin.WxOpen/src/Senparc.Weixin.WxOpen/Senparc.Weixin.WxOpen/Helpers/EncryptHelper.cs","lineNumber":256,"sourceCode":"        /// <summary>\n        /// 解密消息（通过SessionId获取）\n        /// </summary>\n        /// <param name=\"sessionId\"></param>\n        /// <param name=\"encryptedData\"></param>\n        /// <param name=\"iv\"></param>\n        /// <exception cref=\"WxOpenException\">当SessionId或SessionKey无效时抛出异常</exception>\n        /// <returns></returns>\n        public static string DecodeEncryptedDataBySessionId(string sessionId, string encryptedData, string iv)\n        {\n            var sessionBag = SessionContainer.GetSession(sessionId);\n            if (sessionBag == null)\n            {\n                throw new WxOpenException(\"SessionId无效\");\n            }\n\n            if (string.IsNullOrEmpty(sessionBag.SessionKey))\n            {\n                throw new WxOpenException(\"SessionKey无效\");\n            }\n\n            var resultStr = DecodeEncryptedData(sessionBag.SessionKey, encryptedData, iv);\n            return resultStr;\n        }\n\n\n        /// <summary>\n        /// 检查解密消息水印\n        /// </summary>\n        /// <param name=\"entity\"></param>\n        /// <param name=\"appId\"></param>\n        /// <returns>entity为null时也会返回false</returns>\n        public static bool CheckWatermark(this DecodeEntityBase entity, string appId)\n        {\n            if (entity == null)\n            {\n                return false;","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/JeffreySu/WeiXinMPSDK/blob/be573f6f94bdbf718dd5f6cdecb137fbc7ff651e/src/Senparc.Weixin.WxOpen/src/Senparc.Weixin.WxOpen/Senparc.Weixin.WxOpen/Helpers/EncryptHelper.cs#L238-L274","documentation":"Thrown by DecodeEncryptedDataBySessionId when the session exists but its SessionKey is null or empty, making AES decryption of the encrypted payload impossible. Indicates the stored session lacks the session_key issued by WeChat's jscode2session.","triggerScenarios":"Calling DecodeEncryptedDataBySessionId for a session whose SessionKey was never populated (failed js2session, manually created session bag) or was cleared.","commonSituations":"Storing sessions from a jscode2session call that returned an error code; custom session storage that omits SessionKey; partial serialization of the session bag in cache.","solutions":["Ensure jscode2session succeeded and session_key was persisted in the bag before accepting the sessionId","Re-authenticate (wx.login + jscode2session) to obtain a fresh SessionKey","Add a server-side check for SessionKey presence before returning sessionId to the client","Catch WxOpenException and treat as a forced re-login"],"exampleFix":"// before\nvar json = EncryptHelper.DecodeEncryptedDataBySessionId(sessionId, encryptedData, iv);\n// after\nvar bag = SessionContainer.GetSession(sessionId);\nif (bag == null || string.IsNullOrEmpty(bag.SessionKey)) {\n    return ForceRelogin();\n}\nvar json = EncryptHelper.DecodeEncryptedDataBySessionId(sessionId, encryptedData, iv);","handlingStrategy":"validation","validationCode":"var bag = SessionContainer.GetSession(sessionId);\nif (bag == null || string.IsNullOrEmpty(bag.SessionKey)) {\n    return ForceRelogin();\n}","typeGuard":"bool SessionKeyReady(string sessionId) => SessionContainer.GetSession(sessionId)?.SessionKey is { Length: > 0 };","tryCatchPattern":"try {\n    var json = EncryptHelper.DecodeEncryptedDataBySessionId(sessionId, encryptedData, iv);\n} catch (WxOpenException ex) when (ex.Message.Contains(\"SessionKey无效\")) {\n    return Unauthorized(\"session key missing, re-authenticate\");\n}","preventionTips":["Persist session_key only from successful jscode2session responses","Validate SessionKey presence server-side before returning sessionId to the client","Catch jscode2session error codes (e.g. 40029 invalid code) instead of caching empty sessions","Treat this error as a forced re-login signal in the client"],"tags":["weixin","wxopen","session","sessionkey","decryption"],"backgroundTag":"empty-required-field","analyzedSha":"be573f6f94bdbf718dd5f6cdecb137fbc7ff651e","analyzedAt":"2026-09-12T10:01:50.733Z","contentChangedAt":"2026-09-12T10:01:50.733Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}