This guide will take you from zero to making authenticated API requests in under 5 minutes. You’ll register a user, log in, and access a protected endpoint.
Prerequisites
Before you begin, make sure you have:
.NET 8 SDK installed (download here )
Git for cloning the repository
A terminal or command prompt
Optional: curl or Postman for testing (examples use curl)
Verify your .NET installation by running dotnet --version. You should see version 8.0.x or higher.
Step-by-Step Guide
Clone and run the service
Clone the repository and start the service: git clone https://github.com/David-Andino/auth-service-dotnet.git
cd auth-service-dotnet/AuthService
dotnet run
You should see output indicating the service is running: info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
The SQLite database is created automatically on first run. No manual database setup required!
Verify the service is running
Open your browser and navigate to: You should see the Swagger UI with all available endpoints documented. This is your interactive API playground. Swagger is only available in development mode. In production, this endpoint would be disabled.
Register a new user
Create your first user account: curl -X POST http://localhost:5000/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"username": "john_doe",
"email": "[email protected] ",
"password": "SecurePass123!"
}'
Response (201 Created): {
"accessToken" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ,
"refreshToken" : "8f3ZHk9mN2pQr5tVwXyZ1aB4cD6eF8gH..." ,
"accessTokenExpiry" : "2026-03-10T05:15:00Z" ,
"user" : {
"id" : "3fa85f64-5717-4562-b3fc-2c963f66afa6" ,
"username" : "john_doe" ,
"email" : "[email protected] " ,
"createdAt" : "2026-03-10T05:00:00Z"
}
}
Password requirements: minimum 8 characters, must include uppercase, lowercase, numbers, and special characters.
Save your tokens! You’ll need them for the next steps. Export them as environment variables:export ACCESS_TOKEN = "your_access_token_here"
export REFRESH_TOKEN = "your_refresh_token_here"
Access a protected endpoint
Use your access token to get your user profile: curl -X GET http://localhost:5000/api/auth/me \
-H "Authorization: Bearer $ACCESS_TOKEN "
Response (200 OK): {
"id" : "3fa85f64-5717-4562-b3fc-2c963f66afa6" ,
"username" : "john_doe" ,
"email" : "[email protected] " ,
"createdAt" : "2026-03-10T05:00:00Z"
}
If you get a 401 Unauthorized error, check that your token is correctly formatted and hasn’t expired (15-minute lifetime).
Refresh your access token
Access tokens expire after 15 minutes. Use your refresh token to get a new one: curl -X POST http://localhost:5000/api/auth/refresh \
-H "Content-Type: application/json" \
-d '{
"refreshToken": "' $REFRESH_TOKEN '"
}'
Response (200 OK): {
"accessToken" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...NEW_TOKEN" ,
"refreshToken" : "9g4AIj0nO3kRs6uWxYzA2bC5dE7fG9hI...NEW_REFRESH" ,
"accessTokenExpiry" : "2026-03-10T05:30:00Z" ,
"user" : {
"id" : "3fa85f64-5717-4562-b3fc-2c963f66afa6" ,
"username" : "john_doe" ,
"email" : "[email protected] " ,
"createdAt" : "2026-03-10T05:00:00Z"
}
}
Token Rotation: The old refresh token is automatically revoked when you get a new one. Always store the latest tokens!
Update your environment variables with the new tokens: export ACCESS_TOKEN = "new_access_token_here"
export REFRESH_TOKEN = "new_refresh_token_here"
Log out (revoke token)
When you’re done, revoke your refresh token: curl -X POST http://localhost:5000/api/auth/revoke \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN " \
-d '{
"refreshToken": "' $REFRESH_TOKEN '",
"reason": "Manual logout"
}'
Response (200 OK): {
"message" : "Token revocado exitosamente."
}
After revocation, the refresh token can no longer be used to get new access tokens.
Complete Flow Example
Here’s the entire authentication flow in one script:
Complete Flow
Node.js Example
Python Example
#!/bin/bash
# 1. Register a new user
REGISTER_RESPONSE = $( curl -s -X POST http://localhost:5000/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"username": "jane_smith",
"email": "[email protected] ",
"password": "SecurePass456!"
}' )
echo "Registration Response:"
echo $REGISTER_RESPONSE | jq .
# Extract tokens
ACCESS_TOKEN = $( echo $REGISTER_RESPONSE | jq -r '.accessToken' )
REFRESH_TOKEN = $( echo $REGISTER_RESPONSE | jq -r '.refreshToken' )
# 2. Get user profile
echo "\nFetching user profile..."
curl -s -X GET http://localhost:5000/api/auth/me \
-H "Authorization: Bearer $ACCESS_TOKEN " | jq .
# 3. Refresh the token
echo "\nRefreshing tokens..."
REFRESH_RESPONSE = $( curl -s -X POST http://localhost:5000/api/auth/refresh \
-H "Content-Type: application/json" \
-d '{"refreshToken": "' $REFRESH_TOKEN '"}' )
echo $REFRESH_RESPONSE | jq .
# Update tokens
ACCESS_TOKEN = $( echo $REFRESH_RESPONSE | jq -r '.accessToken' )
REFRESH_TOKEN = $( echo $REFRESH_RESPONSE | jq -r '.refreshToken' )
# 4. Log out
echo "\nLogging out..."
curl -s -X POST http://localhost:5000/api/auth/revoke \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN " \
-d '{
"refreshToken": "' $REFRESH_TOKEN '",
"reason": "Script completed"
}' | jq .
Common Errors and Solutions
401 Unauthorized Cause: Invalid or expired access tokenSolution: Use the /api/auth/refresh endpoint to get a new access token using your refresh token.
409 Conflict Cause: Email already exists in the systemSolution: Use a different email address or log in with the existing account.
400 Bad Request Cause: Invalid request data (missing fields, invalid email format, weak password)Solution: Check the response body for specific validation errors and adjust your request.
Understanding Token Lifetimes
Token Type Lifetime Purpose Storage Access Token 15 minutes Authenticate API requests Memory only (never localStorage) Refresh Token 7 days Get new access tokens Secure, HttpOnly cookie or secure storage
Security Best Practice: Never store tokens in localStorage or sessionStorage in web applications. Use secure, HttpOnly cookies or in-memory storage only.
Next Steps
Now that you have the basics working:
Using Swagger UI
Prefer a visual interface? The Swagger UI at http://localhost:5000 lets you:
Click “Authorize” in the top right
Enter your access token in the format: Bearer your_token_here
Try out endpoints with the interactive interface
See real-time request/response data
Swagger automatically includes your token in subsequent requests after you authorize, making testing much easier!