Easy - server signs a msg with the wallet address. Wallet passes that to mint call. Contract verifies known signer and msg are correct. Marks signature as used.
Here is an example implementation: https://github.com/miohtama/smart-contracts/blob/master/contracts/KYCCrowdsale.sol#L31