2.2.2.1 C#/.NET
VerifySpeed C#/.NET Client Library Documentation
The VerifySpeed .NET Client Library allows you to seamlessly integrate user verification features into your application. With support for multiple verification methods like Telegram, WhatsApp, and SMS, you can ensure a secure and reliable verification process for your users.
Setup
Step 1: Intall the Package
First, make sure you have installed the VerifySpeed package:
dotnet add package VerifySpeed.VSCSharp
Step 2: Service Registration
Next, add the VerifySpeed services to your application's dependency injection container in the Startup.cs or Program.cs file.
- .NET 6+
- .NET 5
using VSCSharp;
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
// Register VerifySpeed services with your server key.
builder.Services.AddVerifySpeed("YOUR_SERVER_KEY");
// Add other services
WebApplication app = builder.Build();
// Add your middlewares
app.Run();
using VSCSharp;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Register VerifySpeed services with your server key
services.AddVerifySpeed("YOUR_SERVER_KEY");
// Add other services
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// Add your middlewares
}
}
Usage
Below are examples of how to use the VerifySpeed client in your C# application.
Please read Verification Flow to understand the verification process.
1. Initializing the Client
Before creating a verification, you need to initialize the verification process to retrieve the available verification methods.
using System;
using System.Threading.Tasks;
using VSCSharp.Clients;
using VSCSharp.Exceptions;
public class VerifySpeedExample
{
private readonly IVerifySpeedClient verifySpeedClient;
public VerifySpeedExample(IVerifySpeedClient verifySpeedClient)
{
this.verifySpeedClient = verifySpeedClient;
}
public async Task InitializeVerificationAsync()
{
try
{
//TODO: Replace with the actual remote client IP address.
string clientIp = "192.168.1.1";
Initialization initialization = await verifySpeedClient.InitializeAsync(clientIp);
Console.WriteLine("Available Verification Methods:");
foreach (Method availableMethod in initialization.AvailableMethods)
{
Console.WriteLine($"- {availableMethod.DisplayName} ({availableMethod.MethodName})");
}
// in most cases, you may return the available methods to client.
}
catch (FailedInitializationException exeption)
{
Console.WriteLine($"Initialization failed: {exeption.Message}");
}
}
}
2. Creating a Verification
Once initialized, you can create a verification using the desired method (e.g., Telegram Message, WhatsApp Message).
NOTE: Please read Verification Flow and Verification Methods to understand the verification process.
using System;
using System.Threading.Tasks;
using VSCSharp.Clients;
using VSCSharp.Enums;
using VSCSharp.Exceptions;
using VSCSharp.Models.Commons;
public class VerificationCreationExample
{
private readonly IVerifySpeedClient verifySpeedClient;
public VerificationCreationExample(IVerifySpeedClient verifySpeedClient)
{
this.verifySpeedClient = verifySpeedClient;
}
public async Task CreateVerificationAsync()
{
try
{
//TODO: Replace with the actual remote client IP address.
string clientIp = "192.168.1.1";
CreatedVerification createdVerification = await verifySpeedClient.CreateVerificationAsync(
methodName: "telegram-message",
clientIPv4Address: clientIp,
language: "ar"
);
Console.WriteLine($"Verification Method: {createdVerification.MethodName}");
Console.WriteLine($"Verification Key: {createdVerification.VerificationKey}");
Console.WriteLine($"Deep Link: {createdVerification.DeepLink}");
// Use should return VerificationKey with DeepLink to the your mobile/web app
}
catch (FailedCreateVerificationException exeption)
{
Console.WriteLine($"Failed to create verification: {exeption.Message}");
}
}
}
3. Verifying Verification Tokens (Local Method)
Local verification approach: The EncryptionTool class allows you to verify verification tokens directly on your server without making additional API calls. This method is faster and gives you full control over the verification process, but it cannot detect token reuse.
- Client's Built-in Method
- EncryptionTool Extension Method
The IVerifySpeedClient also provides a built-in verification method that uses your configured server key:
public class ClientVerificationExample
{
private readonly IVerifySpeedClient verifySpeedClient;
public ClientVerificationExample(IVerifySpeedClient verifySpeedClient)
{
verifySpeedClient = verifySpeedClient;
}
public void VerifyTokenUsingClient(string encryptedToken)
{
try
{
// Uses the server key configured during service registration
VerificationResult result = verifySpeedClient.VerifiedVerificationToken(encryptedToken);
Console.WriteLine($"Decrypted Phone Number: {result.PhoneNumber}");
Console.WriteLine($"Verification Method: {result.MethodName}");
Console.WriteLine($"Date of Verification: {result.DateOfVerification}");
Console.WriteLine($"Verification Key: {result.VerificationKey}");
// Process the verified user
}
catch (InvalidVerificationTokenException ex)
{
Console.WriteLine($"Token validation failed: {ex.Message}");
}
catch (FailedDecryptingVerificationTokenException ex)
{
Console.WriteLine($"Token verification failed: {ex.Message}");
}
}
}
This approach is convenient when you want to use the server key that was configured during service registration without having to pass it explicitly.
The VerifiedVerificationToken method is implemented as an extension method on the string type, making it easy to use:
// Direct usage on the encrypted token string
string encryptedToken = "your_encrypted_token_here";
string serverKey = "your_server_key_here";
VerificationResult result = encryptedToken.VerifiedVerificationToken(serverKey);
// Or using the EncryptionTool class directly
var encryptionTool = new EncryptionTool();
VerificationResult result2 = encryptionTool.VerifiedVerificationToken(encryptedToken, serverKey);
This approach gives you more flexibility and control over the verification process.
4. Verifying a Token via API (Enhanced Security Method)
Enhanced Security Approach: The API verification method provides additional security features that local verification cannot offer. When you verify tokens through the VerifySpeed API, you receive information about whether this token has been verified for the first time, which helps prevent token reuse attacks.
Security Benefit: The API method provides firstTimeVerified information that indicates whether the token has been reused or not, making it more secure against replay attacks than local verification alone.
using System;
using System.Threading.Tasks;
using VSCSharp.Clients;
using VSCSharp.Exceptions;
public class TokenVerificationExample
{
private readonly IVerifySpeedClient verifySpeedClient;
public TokenVerificationExample(IVerifySpeedClient verifySpeedClient)
{
verifySpeedClient = verifySpeedClient;
}
public async Task VerifyTokenAsync(string token)
{
try
{
// API verification provides additional security information
GetVerificationResultResponse result = await verifySpeedClient.VerifyTokenAsync(token);
Console.WriteLine($"Verified Phone Number: {result.PhoneNumber}");
Console.WriteLine($"Verification Method: {result.MethodName}");
Console.WriteLine($"Date of Verification: {result.DateOfVerification}");
Console.WriteLine($"Verification Key: {result.VerificationKey}");
// Check if this is the first time this token has been verified
if (result.FirstTimeVerified == "true")
{
Console.WriteLine("✅ This token is being verified for the first time - secure");
// Proceed with your business logic
ProcessVerifiedUser(result.PhoneNumber, result.MethodName, result.DateOfVerification, result.VerificationKey);
}
else
{
Console.WriteLine("⚠️ This token has been verified before - potential security risk");
// Handle token reuse scenario
HandleTokenReuse(result.PhoneNumber, result.VerificationKey);
}
}
catch (FailedVerifyingTokenException exeption)
{
Console.WriteLine($"Token verification failed: {exeption.Message}");
}
}
private void ProcessVerifiedUser(string phoneNumber, string methodName, DateTime verificationDate, string verificationKey)
{
// Implement your business logic here for first-time verification
Console.WriteLine($"Processing verified user: {phoneNumber} via {methodName}");
}
private void HandleTokenReuse(string phoneNumber, string verificationKey)
{
// Implement security measures for token reuse
Console.WriteLine($"Token reuse detected for phone: {phoneNumber}, key: {verificationKey}");
// Log the incident, block the request, or take other security measures
}
}
Models
Initialization Response
-
Initialization: Contains a list of available verification methods.
public record Initialization
{
public List<Method> AvailableMethods { get; init; } = new();
}
public record Method
{
public string MethodName { get; init; } = null!;
public string DisplayName { get; init; } = null!;
}
Created Verification
-
CreatedVerification: Provides details on the created verification, such as a key, its method name, and deep link (not null if method name is
whatsapp-messegeortelegram-message).public record CreatedVerification
{
public string MethodName { get; init; } = null!;
public string VerificationKey { get; init; } = null!;
public string? DeepLink { get; init; }
}
Verification Result
-
VerificationResult: Represents the outcome of verifying a user's token.
/// <summary>
/// Represents the result of a verification process, including the method used,
/// the date of verification, and the verified phone number.
/// </summary>
public record VerificationResult
{
/// <summary>
/// Gets the name of the verification method used.
/// For example, "whatsapp-message", or "sms-otp".
/// </summary>
[JsonPropertyName("methodName")]
public string MethodName { get; init; } = null!;
/// <summary>
/// Gets the date and time when the verification was completed.
/// </summary>
[JsonPropertyName("dateOfVerification")]
public DateTime DateOfVerification { get; init; }
/// <summary>
/// Gets the verified phone number.
/// </summary>
[JsonPropertyName("phoneNumber")]
public string PhoneNumber { get; init; } = null!;
/// <summary>
/// Gets the verification key.
/// </summary>
[JsonPropertyName("verificationKey")]
public string VerificationKey { get; init; } = null!;
}
API Verification Result
-
GetVerificationResultResponse: Represents the result of API verification, including additional security information.
/// <summary>
/// Represents the result of a verification process
/// </summary>
public record GetVerificationResultResponse
{
/// <summary>
/// Gets the name of the verification method used.
/// For example, "whatsapp-message", or "sms-otp".
/// </summary>
[JsonPropertyName("methodName")]
public string MethodName { get; init; } = null!;
/// <summary>
/// Gets the date and time when the verification was completed.
/// </summary>
[JsonPropertyName("dateOfVerification")]
public DateTime DateOfVerification { get; init; }
/// <summary>
/// Gets the verified phone number.
/// </summary>
[JsonPropertyName("phoneNumber")]
public string PhoneNumber { get; init; } = null!;
/// <summary>
/// Gets the verification key.
/// </summary>
[JsonPropertyName("verificationKey")]
public string VerificationKey { get; init; } = null!;
/// <summary>
/// Indicates whether this is the first time the token has been verified. False means it has been verified before by VerifySpeed.
/// </summary>
[JsonPropertyName("firstTimeVerified")]
public string FirstTimeVerified { get; init; } = null!;
}
Exceptions
Handle the following exceptions
- FailedInitializationException: Thrown when initialization fails.
- FailedCreateVerificationException: Thrown when verification creation fails.
- FailedVerifyingTokenException: Thrown when token verification fails.
- InvalidVerificationTokenException: Thrown when the verification token is null, empty, or has an invalid format.
- FailedDecryptingVerificationTokenException: Thrown when token verification fails due to cryptographic errors.
API Example
Here is an use case example of this library for varifying users phone number.
using Microsoft.AspNetCore.Mvc;
using VSCSharp.Clients;
using VSCSharp.Models.Commons;
using VSCSharp.Enums;
[ApiController]
[Route("api/[controller]")]
public class VerificationController : ControllerBase
{
private readonly IVerifySpeedClient verifySpeedClient;
public VerificationController(IVerifySpeedClient verifySpeedClient)
{
verifySpeedClient = verifySpeedClient;
}
[HttpPost("initialize")]
public async Task<IActionResult> PostVerificationInitialization()
{
try
{
var clientIp = HttpContext.Connection.RemoteIpAddress?.ToString();
// NOTE: If your API is behind proxy or load balancer, get client's IP from 'X-Forwarded-For' header
Initialization initialization = await verifySpeedClient.InitializeAsync(clientIp);
return Ok(initialization);
}
catch (Exception exeption)
{
return BadRequest(exeption.Message);
}
}
[HttpPost("create")]
public async Task<IActionResult> PostVerificationCreation([FromBody] PostVerificationCreationRequest request)
{
try
{
var clientIp = HttpContext.Connection.RemoteIpAddress?.ToString();
// NOTE: If your API is behind proxy or load balancer, get client's IP from 'X-Forwarded-For' header
CreatedVerification verification = await verifySpeedClient.CreateVerificationAsync(
request.MethodType,
clientIp
);
return Ok(verification);
}
catch (Exception exeption)
{
return BadRequest(exeption.Message);
}
}
[HttpGet("verify/{token}")]
public async Task<IActionResult> GetVerificationResult(string token)
{
try
{
// Option 1: Use local verification (faster, but no reuse detection)
// Uses the server key configured during service registration
VerificationResult result = verifySpeedClient.VerifiedVerificationToken(token);
// Option 2: Use API verification (slower, but provides reuse detection)
// GetVerificationResultResponse result = await verifySpeedClient.VerifyTokenAsync(token);
// Now you can use verified phone number inside result object
Console.WriteLine($"Verified Phone Number: {result.PhoneNumber}");
Console.WriteLine($"Verification Key: {result.VerificationKey}");
return Ok(result);
}
catch (InvalidVerificationTokenException ex)
{
return BadRequest($"Invalid token: {ex.Message}");
}
catch (FailedDecryptingVerificationTokenException ex)
{
return BadRequest($"Verification failed: {ex.Message}");
}
catch (Exception exeption)
{
return BadRequest(exeption.Message);
}
}
}
public class PostVerificationCreationRequest
{
[Required]
public string MethodType { get; set; }
}
License
This package is distributed under the MIT License.