Implementing Phone Number Acquisition in WeChat Mini Programs with ASP.NET Core

Overview

Obtaining a user's phone number in a WeChat Mini Program requires a multi-step process involving session key exchange and symmetric decryption. This guide covers the complete implementation using ASP.NET Core backend.

Step 1: Session Key Exchange

Frontend Login

In the Mini Program's app.js, invoke wx.login() to obtain an authorization code, then send it to your backend server.

// app.js
App({
  onLaunch() {
    wx.login({
      success: res => {
        if (res.code) {
          wx.request({
            url: 'https://localhost:7122/api/Login/GetSession',
            data: { code: res.code },
            success: data => {
              this.globalData.sessionKey = data.data.session_key;
              this.globalData.openId = data.data.openid;
            }
          });
        }
      }
    });
  },
  globalData: {
    sessionKey: '',
    openId: ''
  }
});

Backend Endpoint

Create a model class to hold the response:

public class SessionResponse
{
    public string session_key { get; set; }
    public string openid { get; set; }
}

Implement the controller endpoint that exchanges the code with WeChat's API:

[Route("api/Login")]
[ApiController]
public class LoginController : ControllerBase
{
    [HttpGet("GetSession")]
    public IActionResult GetSession(string code)
    {
        string appId = Configuration["WeChat:AppId"];
        string appSecret = Configuration["WeChat:AppSecret"];
        
        string requestUrl = $"https://api.weixin.qq.com/sns/jscode2session?appid={appId}&secret={appSecret}&js_code={code}&grant_type=authorization_code";
        
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUrl);
        request.Method = "GET";
        request.ContentType = "text/html;charset=UTF-8";
        
        using var response = (HttpWebResponse)request.GetResponse();
        using var stream = response.GetResponseStream();
        using var reader = new StreamReader(stream, Encoding.UTF8);
        
        string jsonResponse = reader.ReadToEnd();
        SessionResponse sessionData = JsonConvert.DeserializeObject<SessionResponse>(jsonResponse);
        
        return Ok(sessionData);
    }
}

Store sensitive credentials in appsettings.json:

{
  "WeChat": {
    "AppId": "your_appid",
    "AppSecret": "your_secret"
  }
}

Step 2: Phone Number Decryption

Frontend Request

In the page JavaScript file, handle the phone number button callback:

const app = getApp();

Page({
  data: {
    phoneNumber: '',
    userNickname: '',
    showInput: false
  },

  onChooseAvatar(e) {
    this.setData({
      userNickname: e.detail.avatarUrl,
      showInput: true
    });
  },

  onGetPhoneNumber(e) {
    if (e.detail.errMsg === "getPhoneNumber:ok") {
      wx.request({
        url: 'https://localhost:7122/api/Login/DecryptPhone',
        data: {
          encryptedData: e.detail.encryptedData,
          iv: e.detail.iv,
          sessionKey: app.globalData.sessionKey
        },
        method: "GET",
        success: res => {
          this.setData({
            phoneNumber: res.data
          });
        }
      });
    }
  }
});

Backend Decryption Endpoint

[HttpGet("DecryptPhone")]
public IActionResult DecryptPhone(string encryptedData, string iv, string sessionKey)
{
    string phone = DecryptPhoneNumber(encryptedData, iv, sessionKey);
    return Ok(phone);
}

private string DecryptPhoneNumber(string encryptedData, string iv, string sessionKey)
{
    try
    {
        byte[] encryptedBytes = Convert.FromBase64String(encryptedData);
        byte[] keyBytes = Convert.FromBase64String(sessionKey);
        byte[] ivBytes = Convert.FromBase64String(iv);

        using var aesCipher = new AesManaged
        {
            Key = keyBytes,
            IV = ivBytes,
            Mode = CipherMode.CBC,
            Padding = PaddingMode.PKCS7
        };

        ICryptoTransform decryptor = aesCipher.CreateDecryptor();
        byte[] decryptedBytes = decryptor.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);
        
        string jsonResult = Encoding.UTF8.GetString(decryptedBytes);
        JObject phoneData = JObject.Parse(jsonResult);
        
        return phoneData["phoneNumber"]?.ToString() ?? string.Empty;
    }
    catch
    {
        return string.Empty;
    }
}

Technical Details

Session Key Flow

The jscode2session API returns a session_key that serves as the crpytographic key for decrypting user data. This key is tied to the user's session and should not be exposed client-side.

Decryption Algorithm

The phone number data is encrypted using AES-128-CBC with PKCS7 padding. The decryption process requires:

  • Key: The session key obtained from WeChat
  • IV: The initialization vector provided by the frontend
  • Encrypted Data: The encrypted phone number payload

Security Considerations

  • Store AppId and AppSecret in configuration files, never hardcode them
  • The session key should be handled securely on the server
  • Use HTTPS for all API communications
  • Session keys expire and should be refreshed when needed

WXML Template Structure

<button 
  type="primary" 
  open-type="getPhoneNumber" 
  bindgetphonenumber="onGetPhoneNumber">
  Get Phone Number
</button>

The button triggers the onGetPhoneNumber callback which receives the encrypted payload containing the user's phone information.

Tags: WeChat Mini Program ASP.NET Core Phone Number Decryption aes decryption Session Management

Posted on Fri, 21 Aug 2026 16:08:26 +0000 by johnpaine