Thursday, 16 October 2025
Monday, 6 October 2025
๐งพ Steps to Schedule a Batch File in Windows Task Scheduler
Step 1: Create Your Batch File
-
Open Notepad.
-
Type your batch commands, for example:
@echo off echo Running monthly maintenance... :: Add your commands here pause
-
Save the file as
monthly_task.bat
(example name).
๐ Save it in a folder like:C:\Scripts\monthly_task.bat
Step 2: Open Task Scheduler
-
Press Windows + R → type
taskschd.msc
→ press Enter. -
The Task Scheduler window will open.
Step 3: Create a Basic Task
-
Click “Create Basic Task…” on the right side.
-
Enter a name (e.g., “Run Monthly Batch File”).
-
Click Next.
Step 4: Set the Trigger (Schedule)
-
Select “Monthly” → click Next.
-
Under Months, select All months.
-
Under Days, enter 1 (this means 1st day of each month).
-
Set the Start time (e.g., 10:00 AM).
-
Click Next.
Step 5: Set the Action
-
Select “Start a program” → click Next.
-
In the Program/script field, click Browse.
-
Locate and select your
.bat
file (C:\Scripts\monthly_task.bat
). -
Click Next.
Step 6: Finish the Setup
-
Review the summary page.
-
Click Finish.
Step 7: (Optional) Run as Administrator
If your batch file needs admin permissions:
-
Right-click the created task → choose Properties.
-
In the General tab, check “Run with highest privileges.”
-
Click OK.
Step 8: Test the Task
-
Right-click your task → click Run.
-
Confirm your batch file executes properly.
✅ Result:
Your batch file will now automatically run on the 1st of every month at the time you set.
Wednesday, 24 September 2025
Trigger in Azure Functions
๐ข What is a Trigger in Azure Functions?
-
An Azure Function is a small piece of code that runs only when something happens.
-
That “something” is called a trigger.
-
Trigger = automatic starter for your function.
Example:
If you want a function to run every day at 9 AM, a Timer trigger starts it for you.
๐งฉ Key Idea
-
Each function must have exactly one trigger.
-
The trigger decides:
-
When the function runs.
-
What input data is passed to it.
-
๐ Common Trigger Types (with Examples)
Below are the most used Azure Function triggers and what they do.
Trigger Type | What Starts the Function | Simple Example |
---|---|---|
HTTP Trigger | An HTTP request (like a web API call) | Someone sends a GET/POST request to a URL such as https://myfunc.azurewebsites.net/api/hello |
Timer Trigger | A scheduled time (like a cron job) | Run cleanup every night at 2 AM |
Blob Trigger | A file is added or updated in Azure Blob Storage | Automatically resize an image after it’s uploaded |
Queue Storage Trigger | A new message is put in an Azure Storage Queue | Process new orders added to a queue |
Service Bus Trigger | A message arrives in an Azure Service Bus queue or topic | Handle incoming payment notifications |
Event Grid Trigger | An Azure event occurs (e.g., new file in a storage account, resource change) | Send a Slack message when a new file arrives |
Event Hub Trigger | A batch of event-stream data arrives (IoT or telemetry) | Analyze live sensor data |
Cosmos DB Trigger | A document changes in a Cosmos DB collection | Update a cache or run analytics whenever a record changes |
SignalR Trigger (rare) | A SignalR event happens | Send real-time messages to connected clients |
๐ ️ How It Works Step by Step
-
Binding in Code
In the function’s code you specify the trigger type and connection details.[FunctionName("MyHttpFunction")] public static IActionResult Run( [HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequest req, ILogger log) { log.LogInformation("HTTP trigger fired."); return new OkObjectResult("Hello World!"); }
-
Runtime Listens
Azure Functions runtime listens for that event (HTTP call, queue message, timer schedule, etc.). -
Event Happens
When the event occurs, the runtime starts the function automatically and passes in the data (like the HTTP body, message text, or blob contents).
⚙️ Details About Each Trigger
1. HTTP Trigger
-
Use for: APIs or webhooks.
-
Input: Request body, query strings, headers.
-
Return: HTTP response.
-
Security: Set
AuthorizationLevel
(Anonymous, Function, Admin).
2. Timer Trigger
-
Use for: Scheduled tasks like cleanup, backups.
-
Schedule Format: CRON expression, e.g.,
"0 0 2 * * *"
(2 AM daily). -
Example: Nightly email reports.
3. Blob Trigger
-
Use for: Processing files.
-
Works with: Azure Blob Storage containers.
-
Example: Process a CSV when someone uploads it.
4. Queue Storage Trigger
-
Use for: Simple messaging between services.
-
Example: One system drops a message when an order is placed; the function picks it up and processes it.
5. Service Bus Trigger
-
Use for: Enterprise messaging (queues or topics).
-
Example: Payment gateway sends a Service Bus message when a payment succeeds.
6. Event Grid Trigger
-
Use for: Reacting to Azure events in near real-time.
-
Example: Notify a team when a new blob is created.
7. Event Hub Trigger
-
Use for: High-volume event streams like IoT telemetry.
-
Example: Analyze millions of device signals per minute.
8. Cosmos DB Trigger
-
Use for: Reacting to database changes.
-
Example: Automatically update a search index when a product record changes.
๐ง Best Practices
-
One Trigger per Function
-
Each function listens to exactly one event source.
-
-
Keep Functions Short
-
Do small tasks quickly to avoid timeouts.
-
-
Scale Automatically
-
Triggers like Queue, Event Hub, and Blob scale the number of function instances based on event volume.
-
-
Use Bindings for Input/Output
-
You can directly read or write to storage, queues, etc., with simple parameters—no extra code.
-
Quick Recap
-
Trigger = automatic starter for your code.
-
Common triggers: HTTP, Timer, Blob, Queue, Service Bus, Event Grid, Event Hub, Cosmos DB.
-
Each function must have exactly one trigger.
-
Azure Functions automatically listens for the event and runs your code when it happens.
In short:
Azure Function triggers let you run code automatically whenever a specific event (like a request, message, or file upload) occurs—no servers to manage, just write the function and choose the trigger.
CDC
๐ข What is CDC?
CDC is a feature in databases that records every change—when a row is added, updated, or deleted.
Think of it like a CCTV camera for your database.
Whenever data changes, CDC quietly writes a note about it.
๐ก Why is it useful?
-
You can send only new changes to another system (like a data warehouse) instead of copying everything.
-
You can trigger actions when data changes (e.g., send an email when an order ships).
-
It helps with auditing (who changed what and when).
⚙️ How it works (step by step)
-
Turn it on
-
An admin tells the database: “Watch this table for changes.”
-
-
Database watches the transaction log
-
Every insert, update, or delete is already recorded in the database log.
-
CDC reads that log.
-
-
Change table created
-
CDC puts details of each change into a special table (e.g.,
cdc.Orders_CT
). -
This table shows:
-
What kind of change happened (insert/update/delete)
-
Old and new values
-
The time of the change.
-
-
-
Your app reads the changes
-
Your app or ETL job asks: “Give me all changes since last time.”
-
It processes those and remembers the last point it read.
-
๐ง Simple Example
-
You have an Orders table.
-
You update order #5’s status to “Shipped.”
-
CDC writes a row into its change table:
“Order #5 changed from Pending → Shipped at 10:32 AM.”
✅ Good Things
-
No triggers needed: It uses the existing transaction log.
-
Fast: Only new changes are read.
-
Real-time: You see changes almost immediately.
⚠️ Things to keep in mind
-
Change tables can grow big—set cleanup rules.
-
Only users with permission should read CDC data.
๐ Quick Summary
CDC = Automatic change tracker for your database.
It watches every insert, update, or delete and stores those details in a special table, so other apps can easily know exactly what changed without scanning everything.
Tuesday, 23 September 2025
Web API Versioning
1️⃣ Why API Versioning Matters
Imagine you published a REST API for mobile apps:
GET /api/products
-
Later you need a new field or change a parameter.
-
You can’t break old mobile apps that still call the old format.
API versioning lets you:
-
Publish new versions of your API
-
Keep old versions running until clients migrate.
2️⃣ Common Ways to Show the Version
You must tell the server which version the client wants.
Popular options:
Approach | Example call | Pros | Cons |
---|---|---|---|
URL path | /api/v1/products | Very clear, cache friendly | URL changes with every version |
Query string | /api/products?api-version=1.0 | Easy to test | Less obvious in logs |
HTTP header | GET /api/products + x-api-version:1.0 | Clean URLs | Harder to debug in browser |
Accept header (media type) | Accept: application/json; v=1.0 | Follows REST best practice | Requires custom header setup |
You can even combine them.
3️⃣ Official Microsoft Library
Use the NuGet package:
Microsoft.AspNetCore.Mvc.Versioning
This library makes versioning easy.
4️⃣ Basic Setup (Path-based Versioning)
1. Install Package
dotnet add package Microsoft.AspNetCore.Mvc.Versioning
2. Configure in Program.cs
(or Startup.cs
)
builder.Services.AddApiVersioning(options =>
{
options.AssumeDefaultVersionWhenUnspecified = true;
options.DefaultApiVersion = new ApiVersion(1, 0);
options.ReportApiVersions = true; // adds headers: api-supported-versions
});
-
AssumeDefaultVersionWhenUnspecified: if client doesn’t pass a version, use default (1.0).
-
ReportApiVersions: tells clients which versions are available.
3. Version Your Controllers
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiController]
public class ProductsController : ControllerBase
{
[HttpGet]
public string GetV1() => "This is V1";
}
Add a second version:
[ApiVersion("2.0")]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiController]
public class ProductsV2Controller : ControllerBase
{
[HttpGet]
public string GetV2() => "This is V2 with more fields";
}
Now clients call:
/api/v1/products /api/v2/products
5️⃣ Query-String Versioning
If you prefer ?api-version=1.0
:
builder.Services.AddApiVersioning(options =>
{
options.ApiVersionReader = new QueryStringApiVersionReader("api-version");
});
Then the route can simply be [Route("api/[controller]")]
.
Clients call:
/api/products?api-version=1.0
6️⃣ Header-Based Versioning
builder.Services.AddApiVersioning(options =>
{
options.ApiVersionReader = new HeaderApiVersionReader("x-api-version");
});
Client adds header:
x-api-version: 2.0
7️⃣ Multiple Versions in One Controller
You can keep both actions in the same file:
[ApiVersion("1.0")]
[ApiVersion("2.0")]
[Route("api/products")]
[ApiController]
public class ProductsController : ControllerBase
{
[HttpGet, MapToApiVersion("1.0")]
public string GetV1() => "Old result";
[HttpGet, MapToApiVersion("2.0")]
public string GetV2() => "New result";
}
8️⃣ Deleting or Deprecating Versions
Mark an old version as deprecated:
[ApiVersion("1.0", Deprecated = true)]
The response header api-deprecated-versions
warns clients.
9️⃣ Best Practices
-
Choose one clear versioning style and stick to it.
-
Document which versions exist and when they’ll be retired.
-
Use semantic versioning (1.0, 1.1, 2.0) to show backward compatibility.
-
Automate tests for every active version.
-
When possible, design for backward compatibility to avoid breaking clients.
๐ Quick Flow Recap
-
Client requests with a version (URL / query / header).
-
ASP.NET Core checks the version using the configured reader.
-
The correct controller/action for that version executes.
-
Response headers tell the client which versions are supported.
๐ง Key Takeaways
-
API versioning keeps old clients working while you release improvements.
-
Microsoft.AspNetCore.Mvc.Versioning makes it almost plug-and-play.
-
Pick a strategy (URL path, query, or header) and stay consistent.
-
Mark old versions as deprecated before removal.
Monday, 22 September 2025
Kubernetes
๐ข 1️⃣ What is Kubernetes?
-
Kubernetes (K8s) is a container orchestration platform.
-
It manages, deploys, and scales containers automatically.
-
Think of it as a manager for Docker containers in a large system.
Analogy:
-
Docker = single shipping container
-
Kubernetes = entire shipping port with cranes, storage, and delivery trucks
๐ข 2️⃣ Why Kubernetes for .NET Core?
-
Scaling: Automatically increase or decrease the number of instances.
-
Self-healing: Restarts failed containers automatically.
-
Load balancing: Distributes traffic between multiple instances.
-
Rolling updates: Update services without downtime.
-
Service discovery: Easy communication between microservices.
๐ข 3️⃣ Key Kubernetes Concepts
Term | Meaning |
---|---|
Pod | Smallest deployable unit (usually 1 container, can have multiple) |
Node | A server (VM or physical machine) running Kubernetes |
Cluster | A group of nodes managed by Kubernetes |
Deployment | Defines how many replicas of a pod to run and manages updates |
Service | Exposes pods internally or externally for communication |
ConfigMap | Stores configuration (key-value) for pods |
Secret | Stores sensitive info (passwords, API keys) securely |
Namespace | Logical separation of resources in a cluster |
๐ข 4️⃣ Example: Deploy a .NET Core API to Kubernetes
Step 1: Dockerize Your .NET Core App
-
Create Dockerfile and build image as explained earlier.
Step 2: Push Docker Image to Registry
docker tag mywebapi:1.0 mydockerhubuser/mywebapi:1.0 docker push mydockerhubuser/mywebapi:1.0
Step 3: Create Kubernetes Deployment
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mywebapi-deployment
spec:
replicas: 3
selector:
matchLabels:
app: mywebapi
template:
metadata:
labels:
app: mywebapi
spec:
containers:
- name: mywebapi
image: mydockerhubuser/mywebapi:1.0
ports:
- containerPort: 80
-
replicas: number of pods (instances) to run.
Step 4: Expose the Deployment as a Service
service.yaml
apiVersion: v1
kind: Service
metadata:
name: mywebapi-service
spec:
type: LoadBalancer
selector:
app: mywebapi
ports:
- protocol: TCP
port: 80
targetPort: 80
-
LoadBalancer
exposes your API to the outside world.
Step 5: Apply Config to Cluster
kubectl apply -f deployment.yaml kubectl apply -f service.yaml
-
Check pods:
kubectl get pods
-
Check services:
kubectl get svc
๐ข 5️⃣ How Microservices Work on Kubernetes
-
Each microservice runs in its own deployment + pods.
-
Services communicate internally via Kubernetes Service (DNS name).
-
Messages/events can be processed asynchronously using message queues (RabbitMQ, Kafka).
๐ข 6️⃣ Benefits for .NET Core Apps
-
Easy to scale APIs or background workers independently.
-
Can run cross-platform containers (.NET Core works on Linux).
-
Automatic updates and self-healing reduce downtime.
-
Supports microservices architecture with multiple small services.
๐ข 7️⃣ Quick Summary
-
Docker: packages app into container
-
Kubernetes: manages many containers automatically
-
.NET Core + Docker + K8s → scalable, resilient microservices architecture
Docker
๐ข 1️⃣ What is Docker?
-
Docker is a tool to package applications with all dependencies into a container.
-
Container = isolated environment that runs your app anywhere (Windows, Linux, cloud).
-
Benefit: “It works on my machine” problem is solved.
Analogy: Docker is like a shipping container for your app. It includes your app, .NET runtime, libraries, and everything needed.
๐ข 2️⃣ Why Use Docker with .NET Core?
-
Cross-platform: Run .NET Core apps on Linux, Windows, or cloud.
-
Easy deployment: Package app + dependencies.
-
Isolation: No conflicts between apps.
-
Microservices: Each service can run in its own container.
๐ข 3️⃣ Steps to Dockerize a .NET Core App
Step 1: Create a .NET Core App
dotnet new webapi -n MyWebApi
cd MyWebApi
dotnet build
dotnet run
-
Your API runs locally on
http://localhost:5000
.
Step 2: Create a Dockerfile
-
In the root folder, create a file named Dockerfile (no extension):
# 1. Base image with .NET runtime FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base WORKDIR /app EXPOSE 80 # 2. Build image with SDK FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build WORKDIR /src COPY ["MyWebApi.csproj", "./"] RUN dotnet restore "./MyWebApi.csproj" COPY . . RUN dotnet publish "MyWebApi.csproj" -c Release -o /app/publish # 3. Final image FROM base AS final WORKDIR /app COPY --from=build /app/publish . ENTRYPOINT ["dotnet", "MyWebApi.dll"]
Explanation:
-
Stage 1 (base): Runtime image to run the app.
-
Stage 2 (build): SDK image to build and publish the app.
-
Stage 3 (final): Copy published files to runtime image and run.
Step 3: Build Docker Image
docker build -t mywebapi:1.0 .
-
mywebapi
→ image name,1.0
→ version tag. -
Docker reads the Dockerfile and creates the image.
Step 4: Run the Container
docker run -d -p 8080:80 --name mywebapi_container mywebapi:1.0
-
-d
→ run in background -
-p 8080:80
→ map container port 80 to local port 8080 -
--name
→ container name
Now open http://localhost:8080
→ your API is running inside a Docker container!
Step 5: (Optional) Docker Compose
-
Useful if you have multiple services (like API + database).
-
Create
docker-compose.yml
:
version: '3.8'
services:
webapi:
image: mywebapi:1.0
ports:
- "8080:80"
db:
image: mcr.microsoft.com/mssql/server:2019-latest
environment:
SA_PASSWORD: "Your_password123"
ACCEPT_EULA: "Y"
ports:
- "1433:1433"
-
Run with:
docker-compose up -d
๐ข 4️⃣ Tips
-
Always use multi-stage Dockerfile → keeps image size small.
-
Expose only needed ports (
EXPOSE 80
). -
Use environment variables for secrets/configuration.
-
Use .dockerignore to exclude unnecessary files (like
bin
,obj
).
๐ข 5️⃣ Summary
-
Docker packages your .NET Core app + dependencies into a container.
-
Steps:
-
Create .NET Core app
-
Write Dockerfile
-
Build Docker image (
docker build
) -
Run container (
docker run
)
-
-
Optional: Use Docker Compose for multi-container apps.
Concurrency
๐ข 1️⃣ What is Concurrency?
Concurrency means doing multiple things at the same time, or overlapping tasks in your program.
-
In C#, this usually means using multiple threads or tasks.
-
Goal: make your program faster, or responsive (like not freezing UI).
Example:
-
Downloading 5 files at once instead of waiting for one file to finish before starting the next.
๐ข 2️⃣ Ways to Achieve Concurrency in .NET Core
1. Task Parallel Library (TPL)
-
Use the
Task
class to run work asynchronously. -
Example:
using System;
using System.Threading.Tasks;
class Program
{
static void Main()
{
Task t1 = Task.Run(() => Console.WriteLine("Task 1 running"));
Task t2 = Task.Run(() => Console.WriteLine("Task 2 running"));
Task.WaitAll(t1, t2); // wait until all tasks finish
Console.WriteLine("All tasks done");
}
}
✅ Task.Run()
runs work on a thread pool thread.
2. Async / Await
-
For IO-bound tasks (like reading files, HTTP calls), use
async
andawait
. -
Example:
using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
HttpClient client = new HttpClient();
Task<string> t1 = client.GetStringAsync("https://example.com");
Task<string> t2 = client.GetStringAsync("https://example.org");
string[] results = await Task.WhenAll(t1, t2);
foreach (var r in results)
Console.WriteLine(r.Substring(0, 50));
}
}
-
async/await
does not block the thread, so the program can do other work while waiting.
3. Parallel Loops
-
Use
Parallel.For
orParallel.ForEach
to run loop iterations concurrently.
using System;
using System.Threading.Tasks;
class Program
{
static void Main()
{
Parallel.For(0, 5, i =>
{
Console.WriteLine($"Processing {i} on thread {Task.CurrentId}");
});
}
}
-
Automatically splits work across available CPU cores.
4. Concurrent Collections
-
When multiple threads access a collection, use thread-safe collections like:
using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;
class Program
{
static void Main()
{
ConcurrentBag<int> bag = new ConcurrentBag<int>();
Parallel.For(0, 10, i => bag.Add(i));
foreach (var item in bag)
Console.WriteLine(item);
}
}
-
Other options:
ConcurrentQueue
,ConcurrentStack
,ConcurrentDictionary
.
5. Locks (Optional)
-
If you need to protect a resource, use
lock
:
class Counter
{
private int count = 0;
private object lockObj = new object();
public void Increment()
{
lock(lockObj)
{
count++;
}
}
}
-
Only one thread can access the block at a time.
๐ข 3️⃣ Key Tips
-
CPU-bound work →
Task.Run
,Parallel.For
-
IO-bound work →
async/await
-
Shared data → use
Concurrent
collections orlock
-
Avoid blocking threads unnecessarily; async is usually better than
Thread.Sleep
.
๐ข 4️⃣ Quick Summary Table
Type | When to Use | Example |
---|---|---|
Task / TPL | CPU-bound or simple background | Task.Run(() => DoWork()) |
Async / Await | IO-bound (file, API, DB) | await HttpClient.GetStringAsync(url) |
Parallel.For | Loop with independent iterations | Parallel.For(0, 10, i => ...) |
ConcurrentCollection | Multiple threads accessing data | ConcurrentBag<int> |
Lock | Protect shared resources | lock(obj) { ... } |
๐ก Rule of Thumb:
-
Use async/await for non-CPU tasks.
-
Use Task / Parallel for CPU-heavy tasks.
-
Use concurrent collections to safely share data
JWT
๐ข 1. What is JWT?
-
JWT stands for JSON Web Token.
-
It is a secure way to transmit information between a client (like a browser) and a server.
-
The information is digitally signed so it cannot be tampered with.
Analogy:
-
Think of JWT like a sealed envelope with a message inside.
-
Only the server can verify the seal (signature) to know it’s authentic.
๐ข 2. Structure of JWT
A JWT is a string divided into 3 parts separated by dots (.
):
Header.Payload.Signature
-
Header – says what type of token it is and the algorithm used.
{ "alg": "HS256", "typ": "JWT" }
-
Payload – the actual information (claims). Example:
{ "userId": 123, "email": "user@example.com", "role": "admin" }
-
Signature – a hash created from header + payload + secret key.
-
Ensures the token is authentic and unchanged.
-
๐ข 3. How JWT Works
-
User logs in with username/password.
-
Server verifies credentials.
-
Server generates JWT (with user info in payload) and sends it to client.
-
Client stores JWT (usually in local storage or cookies).
-
For future requests, client sends JWT in HTTP header:
Authorization: Bearer <token>
-
Server verifies JWT signature. If valid, user is authenticated.
๐ข 4. JWT in C# (.NET Core / .NET 5+)
Step 1: Install NuGet package
Install-Package System.IdentityModel.Tokens.Jwt
Step 2: Create a JWT
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using Microsoft.IdentityModel.Tokens;
using System.Text;
class Program
{
static void Main()
{
string secretKey = "my_super_secret_key_123!"; // keep it safe
var key = Encoding.ASCII.GetBytes(secretKey);
// 1. Create claims (user info)
var claims = new[]
{
new Claim("userId", "123"),
new Claim(ClaimTypes.Email, "user@example.com"),
new Claim(ClaimTypes.Role, "Admin")
};
// 2. Create token descriptor
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Expires = DateTime.UtcNow.AddHours(1),
SigningCredentials = new SigningCredentials(
new SymmetricSecurityKey(key),
SecurityAlgorithms.HmacSha256Signature)
};
// 3. Create token
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor);
var jwt = tokenHandler.WriteToken(token);
Console.WriteLine("JWT Token:");
Console.WriteLine(jwt);
}
}
Step 3: Validate JWT
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(secretKey);
var validationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false,
ClockSkew = TimeSpan.Zero
};
try
{
var principal = tokenHandler.ValidateToken(jwt, validationParameters, out var validatedToken);
Console.WriteLine("Token is valid!");
Console.WriteLine("UserId: " + principal.FindFirst("userId")?.Value);
}
catch
{
Console.WriteLine("Invalid Token");
}
๐ข 5. Important Points
-
Keep secret key safe! If leaked, attackers can create valid tokens.
-
Do not store sensitive info like passwords in the payload. JWT is only base64 encoded, not encrypted.
-
Expiration is important. Never issue a token without expiry.
-
Bearer token in HTTP header is standard.
๐ข Summary
-
JWT = Header + Payload + Signature
-
Used for authentication and authorization
-
Signed so server can trust it
-
In C#, use System.IdentityModel.Tokens.Jwt to create & verify tokens