Skip to content

zedmakesense/session-authentication-service

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

session-authentication-service

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.


Tech Stack

  • 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

Requirements

  • Go 1.25+ (check with go version)
  • PostgreSQL accessible at localhost:5432 (default DSN)

Setup

  1. Clone the repository:

    git clone https://github.com/zedmakesense/session-authentication-service.git
    cd session-authentication-service
  2. Copy the environment sample file:

    cp .env.sample .env
  3. Edit .env with 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

Database Schema

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
);

Running

  1. Download dependencies:

    go mod download
  2. 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.


API Reference

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

Token Details

  • 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

Endpoints

GET /health

Health check endpoint.

Response:

{
  "status": "OK"
}

POST /register

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.


POST /login

Login with credentials.

Request:

{
  "username": "johndoe",
  "password": "securepassword123"
}

Response: 200 OK
Sets access_token and refresh_token cookies.

Error: 401 Unauthorized if invalid credentials.


POST /logout

Logout and invalidate the current session.

Headers: Authorization: Bearer <access_token> (or cookie)

Response: 200 OK
Clears access_token and refresh_token cookies.


POST /refresh

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.


GET /content

Protected endpoint example (requires authentication).

Headers: Authorization: Bearer <access_token> (or cookie)

Response:

{
  "message": "This is protected content",
  "user": "johndoe"
}

POST /change-password

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 /delete

Delete the user's account and all associated sessions.

Headers: Authorization: Bearer <access_token> (or cookie)

Response: 200 OK


Example curl Commands

# 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

Project Structure

.
├── 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

Security Notes

  • Tokens are stored as SHA-256 hashes in the database, not plaintext
  • Sessions can be revoked server-side via revoked_at timestamp
  • Password changes automatically revoke all other sessions
  • CORS is configured to allow http://localhost:3000 only

About

A simple session authentication service.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published