Designing a Scalable Multi‑Account Login System
This article walks through the design of a unified multi‑account login system, covering phone‑number registration, password‑optional login, third‑party integration, database schema separation, pros and cons, and a one‑click carrier‑based authentication flow.
1. Self‑built login system
1.1 Phone number registration
Each phone number corresponds to a user; the phone number is mandatory.
Process:
Client sends the entered phone number to the server. The server checks whether the number already exists. If not, it generates a random verification code, stores the phone‑code pair in Redis with a typical 5‑minute expiry, and sends the code via SMS.
User receives the code, fills the code together with basic information (e.g., password), and submits to the server. The server validates the code against the entry in Redis. On success, a user account is created and the password hash is saved.
After registration, the user can log in with phone number + password.
Problems:
Poor user experience – users must obtain a code, fill several fields, and register before they can use the app.
Passwords are easy to forget; recovery requires a separate “forgot password” flow.
1.2 Optimized registration/login (password optional)
Login can be performed directly with phone number + verification code regardless of prior registration, while still supporting the traditional phone number + password method.
Process:
User enters the phone number; the server generates a verification code, stores it in Redis (5‑minute expiry), and sends the code via SMS.
User submits the received code. The server checks the code in Redis. If it matches, login succeeds. For existing users, their profile is fetched; for new users, they are prompted (non‑mandatory) to complete additional profile information.
After logging in with phone number + verification code, the user may optionally set a password, after which phone number + password becomes a valid login method as well.
User table design (fields):
id – user identifier
user_name – username
user_password – password hash
user_mobile – phone number
state – account status
more – other information
1.3 Third‑party account integration
1.3.1 Weibo login
Client invokes Weibo’s login page, obtains an access_token, and calls Weibo’s API to fetch user information. The server creates a local account linked to the Weibo UID, enabling future logins via Weibo.
Weibo user info table (fields):
id – primary key
user_id – local user identifier
uid – Weibo unique ID
access_token – authorization token
1.3.2 Multiple third‑party providers
When providers such as QQ, WeChat, NetEase, etc., also open login, a naïve approach would copy the Weibo user table for each provider and write separate integration code, which quickly becomes unmanageable.
2. Optimizing the account system
2.1 Analysis of the original system
Self‑built login uses either phone + password or phone + verification code; both are essentially “user info + password” verification.
Third‑party login also follows the “user info + password” pattern, where the third‑party ID acts as the identifier and the access_token serves as a time‑limited password.
2.2 New account system
2.2.1 Data table design
User basic information table (fields):
id – user identifier
nickname – display name
avatar – profile picture URL
more – other profile data
User authorization table (fields):
id – primary key
user_id – reference to the user basic table
identity_type – type of login (e.g., phone, email, WeChat, Weibo)
identifier – the unique identifier in the third‑party system (phone number, email, openId, etc.)
credential – stored password for native accounts or token for third‑party accounts
Explanation:
The user basic table stores only non‑credential data (nickname, avatar, etc.).
All login‑related data resides in the user_auths table, establishing a one‑to‑many relationship (a user can have many auth records).
A unified verified flag in user_auths replaces separate phone_verified and email_verified columns, simplifying verification status checks.
Tracking login timestamps and IP addresses in user_auths enables usage‑habit analysis (e.g., “Weibo not used for two years, WeChat bound for 300 days”).
Multiple credentials of the same type can be bound to a single user (e.g., several WeChat accounts, multiple emails), or the system can enforce a one‑record rule per type.
2.2.2 Login flow
phone + verification code– same flow as in section 1.2. email/phone + password – the server receives type='phone' (or type='email') and identifier='the phone or email', looks up the corresponding credential in user_auths, compares the hash, and on match retrieves the user_id to fetch the profile.
Third‑party login (e.g., WeChat): the client sends type='weixin' and identifier='WeChat openId'. If a record exists, login succeeds and the stored token may be refreshed; the example assumes a trusted channel to the provider.
2.2.3 Advantages
Login types can be extended indefinitely; adding a new provider incurs minimal development effort.
The unified verified field makes it easy to see verification status across all login methods.
Storing timestamps and IPs per auth record enables detailed usage tracking.
Login credentials (email, phone, etc.) are treated as display attributes, not core identity data.
Users may bind any number of credentials of the same type, or the system can enforce a single record per type.
2.2.4 Disadvantages
When a user has multiple login methods (email, username, phone), password changes must be synchronized across all records; otherwise inconsistent login states arise (e.g., email + new password works but phone + old password still logs in).
Code complexity grows: handling many edge cases such as third‑party accounts that are already linked, unlinked, or need binding introduces additional branching logic.
3. One‑click login
3.1 Background
The traditional phone + verification code flow takes over 20 seconds, requires SMS delivery, and is vulnerable to code interception.
3.2 Device number authentication (carrier‑based)
By querying the SIM card data from the carrier, the app can confirm that the entered number matches the device’s own number. If the carrier returns the actual number, the user no longer needs to type it.
Typical SDK flow (Alibaba Cloud SDK compatible with China Mobile, China Unicom, and China Telecom):
SDK initialization – provide the AppKey and AppSecret.
Invoke the SDK to display the authorization page. The SDK first requests a masked phone number from the carrier; the page shows the mask and the carrier agreement for user consent.
User agrees and taps the login button; the SDK obtains a token for the number request.
Send the token to the backend, which calls the carrier’s one‑click login API to retrieve the real phone number. The backend then creates or logs in the user with that number and returns the result to the client.
4. Summary
There is no universally best solution; choose the design that fits the current system, balancing extensibility, user experience, and implementation complexity.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
IoT Full-Stack Technology
Dedicated to sharing IoT cloud services, embedded systems, and mobile client technology, with no spam ads.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
