natapp Tunnel Setup
Registration, Download, and Installation
- Open the natapp official website and create an account.
- Download the client for your operating system.
- Grant execution permission if you are on Linux or macOS:
chmod 755 natapp
Token and Tunnel Configuration
- Log in to the web console and purchase a free tunnel.
- Navigate to the tunnel list to find the
authtokenassigned to your account.
Exposing a Local Port
Start the tunnel by specifying your token. The following command forwards traffic to the service running on your machine:
./natapp -authtoken=YOUR_AUTHTOKEN
Once connected, the terminal displays a random public URL that maps to your local server.
ngrok Tunnel Setup
Account and Client Download
- Register at the ngrok dashboard.
- Download the ngrok binary from the official download page.
Token Configuration
After logging into the dashboard, copy your authentication token and configure the local client:
./ngrok config add-authtoken YOUR_TOKEN
Verify the token is stored correctly:
./ngrok config check
Exposing a Local Service
To make a locally running HTTP service on port 9999 publicly accessible, run:
./ngrok http 9999
A generated ngrok URL appears in the terminal. When accessed through a browser, a warning interstitial page may appear. Ngrok offers several ways to bypass this page:
- Click the Visit Site button.
- Add the
ngrok-skip-browser-warningheader to requests. - Upgrade to a paid plan.
Fixed Domains via Reserved Tunnels
Paid accounts can reserve a subdomain, which keeps the public URL unchanged across restarts. After reserving a domain in the dashboard, launch the tunnel with:
./ngrok http --domain=your-reserved-domain.ngrok-free.app 9999
WeChat Official Account Callback Configuration
Creating a Test Account
Navigate to the WeChat sandbox environment and scan the QR code to log in. A test app ID and app secret are generated automatically.
Callback Handling Code
Implement two endpoints — one for the initial GET verification request and another for POST messages sent by WeChat.
@GetMapping("/wechat/callback")
public String verifyServer(@RequestParam("signature") String signature,
@RequestParam("timestamp") String timestamp,
@RequestParam("nonce") String nonce,
@RequestParam(name = "echostr", required = false) String echoStr) {
logger.info("WeChat GET validation");
logger.debug("sig={}, ts={}, nonce={}", signature, timestamp, nonce);
return echoStr;
}
@PostMapping(value = "/wechat/callback", produces = "text/xml;charset=UTF-8")
public String receiveMessage(@RequestBody(required = false) String xmlBody,
@RequestParam("signature") String signature,
@RequestParam("timestamp") String timestamp,
@RequestParam("nonce") String nonce,
@RequestParam(name = "encrypt_type", required = false) String encryptType,
@RequestParam(name = "msg_signature", required = false) String msgSignature) {
logger.info("WeChat POST event");
logger.debug("sig={}, ts={}, nonce={}, encType={}", signature, timestamp, nonce, encryptType);
logger.debug("XML body: {}", xmlBody);
// Process the message and return a response XML or empty
return "success";
}
Ensure the correct content type is set for the POST endpoint so that WeChat can parse the response.
Binding the Callback URL
In the test account configuration page, fill in the URL field with the tunnel address followed by the callback path (for example, https://your-tunnel.ngrok-free.app/wechat/callback). Do not include the protocol prefix in the web UI — only the domain and path. Submit the configuration; WeChat sends a GET request to verify the endpoint. Once verified, the callback is active.
Comparison Summary
| Tool | Protocol Suppport | Domain Behavior | WeChat Compatibility |
|---|---|---|---|
| ngrok | HTTP & HTTPS | Reserved subdomain (paid) or random | Requires header or click skip; may fail in some cases |
| natapp | HTTP only | Random domain each restart | No interstitial page; simpler for testing |