The Admin Powers to My RFID + FastAPI System is Here! (Part 2)

In Part 1, I built a simple RFID-based login/logout system using a NodeMCU and FastAPI.
It worked, one can scan a card, and it logs the event in a database. Simple? Yes, It is.
But I realized anyone could register an RFID UID just by hitting the right endpoint. I did not simply want that because that’s not secure. That’s not how actual access systems work.
So in Part 2, I fixed it.
I added admin-only registration and made the process even smoother using RFID scans.
The Idea
Only an admin should be able to register new users. Yeah it makes sense right.
Instead of manually adding UID in Swagger or Postman, I wanted this:
Admin enters user name + mobile number
Then scans the RFID card
The backend binds the scanned UID to that user
Done.
That’s exactly what this part is about.
What I Added
1. Admin Login with OAuth2 + JWT
I created a /login route where admin sends credentials:
POST /login
username: admin
password: admin123
If valid, it returns a JWT token.
This token is required for admin-only actions like registration.
{
"access_token": "eyJhbGciOiJIUzI1...",
"token_type": "bearer"
}
2. /start_registration — Begin the Process
The admin sends the name and mobile number of the new user.
POST /start_registration
Authorization: Bearer <token>
{
"name": "Adithya",
"mobile_number": "1234567890"
}
This doesn’t write anything to the DB yet.
It just stores the data temporarily in memory (pending_user_data) and waits for a card to be scanned.
3. Scan the Card (using NodeMCU like before)
Once the RFID card is scanned, the same /access endpoint is hit.
But this time because the system sees a pending registration, it treats the scanned UID as a new user and completes the registration.
If everything is good that is :
UID is unique that is not already registered
Mobile number is unique
Within 30 seconds the card’s scanned
Then it creates the user and clears the temporary data (pending_user_data).
Timeout Logic
To keep things clean, I added a 30-second timeout.
If the admin doesn’t scan a card within 30 seconds of starting the registration, the system automatically clears the pending data.
{
"detail": "Registration expired. Please start again."
}
Duplicate Protection
I also added checks so one can’t:
Reuse a UID
Reuse a mobile number
If either one is already in the DB, it throws an error.
{
"detail": "User already exists."
}
Still Works Like Before (for regular scans)?
Yes, Once registration is complete, the user can just scan their card like before, the backend logs whether it was a login or logout.
No change there.
Flow Summary
Here’s the full flow now:
Admin logs in → gets token
Admin sends name & mobile to start registration
System stores it temporarily
User scans RFID card
System binds UID to user and saves to DB
From now on, that UID triggers login/logout
If you don’t scan a card in 30 sec → timeout
If you scan a card that’s already registered → error
If you try to use /start_registration without token → unauthorized
Feels tight. Feels secure.
Visual Flow

Source Code
You can find the complete backend code for this system here:
GitHub Repo – RFIDAuthX
Tech Behind It
OAuth2PasswordBearerfrom FastAPIJWT encode/decode using
python-josePassword hashing with
passlibShared state using a Python dictionary (
pending_user_data)Timeout logic using
datetime.utcnow()+timedelta
What I Learned
How to use OAuth2 in FastAPI
How JWT tokens actually work
How to share state temporarily between endpoints(pending user data)
Why timeout logic makes systems more reliable
What’s Next (Part 3?)
Some ideas I'm planning:
/cancel_registrationto abort an in-progress registration/usersand/logsendpoints for adminMight even make a frontend dashboard, who knows
💬 Got feedback, questions, or suggestions?
I’d love to hear what you think — feel free to reach out at
👉 www.iadiee.xyz/#contact
