refactor(auth): make OTP login a two step process #33

Closed
opened 2025-07-30 14:13:57 +00:00 by chartgerink · 1 comment
Owner

Currently, upon logging in we have to send the OTP directly with the request. However, in reality, we will not know whether this is needed for logging into an account. This will prove unworkable once the front end is being implemented.

New process will have to be:

  1. Client enters login
  2. Server verifies log in and either (1) sends JWT (no OTP) or (2) sends OTP challenge
  3. Client receives OTP challenge
  4. Client enters OTP code
  5. Server verifies OTP code
  6. Client receives JWT
Currently, upon logging in we have to send the OTP directly with the request. However, in reality, we will not know whether this is needed for logging into an account. This will prove unworkable once the front end is being implemented. New process will have to be: 1. Client enters login 2. Server verifies log in and either (1) sends JWT (no OTP) or (2) sends OTP challenge 2. Client receives OTP challenge 3. Client enters OTP code 4. Server verifies OTP code 5. Client receives JWT
Author
Owner

This is in some more detail:

Example Flow

Client sends login request:

{
  "username": "user@example.com",
  "password": "password123"
}

Server responds with 401 if 2FA is required:

{
  "message": "2FA is required",
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoidXNlcjEyMyIsInRpbW1hbnN0IjoyNTQwLCJleHBpcmF0aW9uX3RpbWUiOjI1NDAsIm5vbmNlIjoicmFuZG9tX25vbmNlX3ZhbHVlIn0.abc123xyz"
}

Client sends OTP verification request:

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoidXNlcjEyMyIsInRpbW1hbnN0IjoyNTQwLCJleHBpcmF0aW9uX3RpbWUiOjI1NDAsIm5vbmNlIjoicmFuZG9tX25vbmNlX3ZhbHVlIn0.abc123xyz",
  "otp": "123456"
}

Server verifies OTP and responds with JWT:

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoidXNlcjEyMyIsImV4cCI6MTY1NDA3MzQwMH0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
}

Note that we use access_token and refresh_token instead :)

This is in some more detail: ## Example Flow ### Client sends login request: ```json { "username": "user@example.com", "password": "password123" } ``` ### Server responds with 401 if 2FA is required: ```json { "message": "2FA is required", "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoidXNlcjEyMyIsInRpbW1hbnN0IjoyNTQwLCJleHBpcmF0aW9uX3RpbWUiOjI1NDAsIm5vbmNlIjoicmFuZG9tX25vbmNlX3ZhbHVlIn0.abc123xyz" } ``` ### Client sends OTP verification request: ```json { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoidXNlcjEyMyIsInRpbW1hbnN0IjoyNTQwLCJleHBpcmF0aW9uX3RpbWUiOjI1NDAsIm5vbmNlIjoicmFuZG9tX25vbmNlX3ZhbHVlIn0.abc123xyz", "otp": "123456" } ``` ### Server verifies OTP and responds with JWT: ```json { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoidXNlcjEyMyIsImV4cCI6MTY1NDA3MzQwMH0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" } ``` --- Note that we use `access_token` and `refresh_token` instead :)
chartgerink canceled time tracking 2025-08-08 08:33:05 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: libscie/researchequals-api#33
No description provided.