A minimal session-based authentication backend implemented in Go. The service provides user registration, login, session storage (access + refresh token hashing), token revocation, password changes that revoke other sessions, and basic user deletion.
- Language: Go 1.25+
- Database: PostgreSQL
- Token Storage: SHA-256 hashed tokens (stored as bytes)
- HTTP Router: Go standard library
http.ServeMux - CORS: rs/cors
- Go 1.25+ (check with
go version) - PostgreSQL accessible at
localhost:5432(default DSN)
-
Clone the repository:
git clone https://github.com/zedmakesense/session-authentication-service.git cd session-authentication-service -
Copy the environment sample file:
cp .env.sample .env
-
Edit
.envwith your database credentials:PORT=8080 DB_NAME=your_db_name DB_USER=your_db_user DB_PASSWORD=your_user_password POSTGRES_PASSWORD=your_postgres_password
Create the following tables in your PostgreSQL database:
CREATE TABLE users (
user_id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
username TEXT UNIQUE NOT NULL,
password_hash TEXT NOT NULL
);
CREATE TABLE sessions (
session_id SERIAL PRIMARY KEY,
access_token_hash BYTEA NOT NULL,
refresh_token_hash BYTEA NOT NULL,
user_id INT REFERENCES users(user_id),
access_expires_at TIMESTAMPTZ,
refresh_expires_at TIMESTAMPTZ,
revoked_at TIMESTAMPTZ
);-
Download dependencies:
go mod download
-
Run the server:
go run ./cmd/server
The server listens on the port specified by PORT (default 8080). It implements graceful shutdown on SIGINT / SIGTERM.
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /health |
No | Health check |
| POST | /register |
No | Create a new account |
| POST | /login |
No | Login with credentials |
| POST | /logout |
Yes | Logout and clear session |
| POST | /refresh |
No | Refresh access token |
| GET | /content |
Yes | Protected content (example) |
| POST | /change-password |
Yes | Change password |
| DELETE | /delete |
Yes | Delete account |
- Access Token: Expires in 15 minutes
- Refresh Token: Expires in 7 days
- Tokens are 32 random bytes, URL-safe base64 encoded, then SHA-256 hashed before storage
- Tokens are delivered via HTTP-only cookies
Health check endpoint.
Response:
{
"status": "OK"
}Create a new user account.
Request:
{
"name": "John Doe",
"username": "johndoe",
"password": "securepassword123"
}Response: 201 Created
Sets access_token and refresh_token cookies.
Error: 409 Conflict if username already exists.
Login with credentials.
Request:
{
"username": "johndoe",
"password": "securepassword123"
}Response: 200 OK
Sets access_token and refresh_token cookies.
Error: 401 Unauthorized if invalid credentials.
Logout and invalidate the current session.
Headers: Authorization: Bearer <access_token> (or cookie)
Response: 200 OK
Clears access_token and refresh_token cookies.
Refresh the access token using a valid refresh token.
Headers: Cookie refresh_token must be present.
Response: 200 OK
Sets new access_token and refresh_token cookies.
Error: 401 Unauthorized if refresh token is invalid or expired.
Protected endpoint example (requires authentication).
Headers: Authorization: Bearer <access_token> (or cookie)
Response:
{
"message": "This is protected content",
"user": "johndoe"
}Change the user's password. This invalidates all other sessions.
Headers: Authorization: Bearer <access_token> (or cookie)
Request:
{
"new_password": "newsecurepassword123"
}Response: 200 OK
Delete the user's account and all associated sessions.
Headers: Authorization: Bearer <access_token> (or cookie)
Response: 200 OK
# Register a new user
curl -X POST http://localhost:8080/register \
-H "Content-Type: application/json" \
-d '{"name": "John Doe", "username": "johndoe", "password": "securepassword123"}' \
-c cookies.txt
# Login
curl -X POST http://localhost:8080/login \
-H "Content-Type: application/json" \
-d '{"username": "johndoe", "password": "securepassword123"}' \
-c cookies.txt
# Access protected content
curl -X GET http://localhost:8080/content \
-b cookies.txt
# Logout
curl -X POST http://localhost:8080/logout \
-b cookies.txt
# Change password
curl -X POST http://localhost:8080/change-password \
-H "Content-Type: application/json" \
-d '{"new_password": "newpassword123"}' \
-b cookies.txt
# Delete account
curl -X DELETE http://localhost:8080/delete \
-b cookies.txt
# Refresh token
curl -X POST http://localhost:8080/refresh \
-b cookies.txt.
├── cmd/server # Server entrypoint (graceful shutdown, http.Server)
├── internal/
│ ├── server # Server wiring, route registration, middleware
│ ├── service # Business logic (token generation, register/login, validation)
│ ├── repository # Database access (users, sessions queries)
│ └── handlers # HTTP handlers
├── .env.sample # Example environment variables
├── go.mod # Go module file
└── go.sum # Go module checksums
- Tokens are stored as SHA-256 hashes in the database, not plaintext
- Sessions can be revoked server-side via
revoked_attimestamp - Password changes automatically revoke all other sessions
- CORS is configured to allow
http://localhost:3000only