JeffreySu/WeiXinMPSDK · error · WxOpenException

SessionKey无效(02)

Error message

SessionKey无效(02)

What it means

Thrown by EncryptHelper.CheckSignature when the session exists but its SessionKey is null or empty. CheckSignature computes HMAC/SHA1 of rawData with the SessionKey, so verification is impossible without one. Usually means the session record was created without a valid SessionKey from the wx jscode2session exchange.

Solutions

  1. Verify the js2session exchange succeeded (check errcode) and that SessionKey was stored in the bag before responding to the client
  2. Re-run the login flow to regenerate a session with a valid SessionKey
  3. Validate SessionKey presence on the server before handing out the sessionId
  4. Catch WxOpenException (02) and prompt re-authentication

Example fix

// before — caching session even when js2session failed
await SessionContainer.AddSessionAsync(sessionId, appId, openId, sessionKey: result.session_key ?? "");
// after
if (string.IsNullOrEmpty(result.session_key)) throw new WxOpenException("js2session failed: " + result.errcode);
await SessionContainer.AddSessionAsync(sessionId, appId, openId, result.session_key);
Defensive patterns

Strategy: validation

Validate before calling

var bag = SessionContainer.GetSession(sessionId);
if (bag == null || string.IsNullOrEmpty(bag.SessionKey)) {
    return ForceRelogin(); // cannot verify signature without SessionKey
}

Type guard

bool HasValidSessionKey(SessionBag bag) => bag != null && !string.IsNullOrEmpty(bag.SessionKey);

Try / catch

try {
    var ok = EncryptHelper.CheckSignature(sessionId, rawData, compareSignature);
} catch (WxOpenException ex) when (ex.Message.Contains("SessionKey无效")) {
    return Unauthorized("session missing SessionKey, re-authenticate");
}

Prevention

When it happens

Trigger: Calling CheckSignature with a sessionId whose SessionContainer entry has an empty SessionKey — e.g. session stored from a failed/short-circuited js2session call, or session key explicitly cleared.

Common situations: Custom code inserting session bags manually without a SessionKey; wx jscode2session returned an error (invalid js_code) but the session was still cached; cache entries partially deserialized/trimmed.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of JeffreySu/WeiXinMPSDK@be573f6f94 (2026-09-12). Data as JSON: /api/errors/9c50db24ecea03cc. Report an issue: GitHub.

Appendix: source

Thrown at src/Senparc.Weixin.WxOpen/src/Senparc.Weixin.WxOpen/Senparc.Weixin.WxOpen/Helpers/EncryptHelper.cs:116

        /// <summary>
        /// 比较签名是否正确
        /// </summary>
        /// <param name="sessionId"></param>
        /// <param name="rawData"></param>
        /// <param name="compareSignature"></param>
        /// <exception cref="WxOpenException">当SessionId或SessionKey无效时抛出异常</exception>
        /// <returns></returns>
        public static bool CheckSignature(string sessionId, string rawData, string compareSignature)
        {
            var sessionBag = SessionContainer.GetSession(sessionId);
            if (sessionBag == null)
            {
                throw new WxOpenException("SessionId无效(01)");
            }

            if (string.IsNullOrEmpty(sessionBag.SessionKey))
            {
                throw new WxOpenException("SessionKey无效(02)");
            }

            var signature = GetSignature(rawData, sessionBag.SessionKey);
            return signature == compareSignature;
        }

        #endregion

        #region 解密

        #region 私有方法

        private static byte[] AES_Decrypt(String Input, byte[] Iv, byte[] Key, int keySize = 128)
        {
#if NET462
            RijndaelManaged aes = new RijndaelManaged();
#else
            SymmetricAlgorithm aes = Aes.Create();

View on GitHub (pinned to be573f6f94)