Everyone who has written a backend, sooner or later, has to fight a hard battle with “login.” It looks like a small feature — a username, a password, a button — but anyone who has actually built it knows this is the part of the whole system with the deepest pits, the most painful changes, and the most fatal failures.

It’s a hassle not because the technology is hard, but because it sits right at the intersection of three parties’ interests: users want convenience, product wants growth, and security wants an airtight defense. These three are naturally at odds. Every inch you move toward one, the other two start crying out.

This article wants to lay this “hassle” out clearly: how mainstream vendors do it now, where each approach rots, how it might change in the future, and — if you have to start today — how to actually ship it.


1. Survey the battlefield: what mainstream vendors use now

If you sign up for any halfway serious app today, you’ll find that login has long ceased to be a single “account + password” road. Today’s mainstream approaches roughly fall into five categories.

1. Phone number + SMS code

This is the absolute ruler of the Chinese internet. Open Weibo, Douyin, Meituan, Pinduoduo — the first screen is almost uniformly “enter phone number → receive code → enter.”

It wins because it solves three problems at once: a phone number is inherently real-name (the carrier did the KYC for you), you don’t have to remember a password, and registration and login are the same action. For a product manager, this means an extremely high registration conversion rate — one fewer “set a password” step means one fewer batch of dropped users.

The cost: you’ve handed the lifeblood of your identity to the carrier and the SMS channel.

2. Email + password

This is the default paradigm globally (especially in the West). GitHub, Google, Notion, nearly all SaaS use email as the account’s main body.

Email’s upside is that it’s globally universal, works across countries, doesn’t depend on a carrier, and can carry the recovery flow. An email address is almost your “primary key” on the internet. The downsides come later.

3. Third-party login (OAuth / social login)

“Log in with WeChat,” “Sign in with Google,” “Continue with Apple” — essentially outsourcing identity authentication to a big platform you already trust.

Its killer feature: the user doesn’t have to type anything. One click, authorize, and you’re in. For developers, you also avoid the risk of storing passwords yourself (the password never passes through your server). The cost is you’re bound to the platform’s ecosystem, and the user’s account system is actually not in your hands.

A passwordless variant: you enter your email, the system sends you an email with a one-time link, and clicking it logs you in. Slack and Medium relied on this early on.

It completely deletes the “remember a password” problem, and the security model is simple and clear. But it bets the smoothness of the entire login experience on “whether the email arrives instantly” — and email, when it’s slow, can be slow enough to make you question life.

5. Passkey / WebAuthn

This is the newest direction, and the one vendors are pushing hard. Apple, Google, and Microsoft already support it fully. It’s based on public/private-key cryptography and uses your device’s biometrics (fingerprint, Face ID) to complete authentication, with no stealable password stored on the server side at all.

This is the widely acknowledged “theoretically optimal” approach; we’ll cover it separately at the end.

The diagram below places these five along two dimensions — “how carefree for the user” and “security strength” — so you can intuitively see the niche each occupies:

graph TD
    A["The login spectrum"] --> B["SMS code
carefree: high / security: medium"] A --> C["Email + password
carefree: low / security: medium"] A --> D["Third-party login
carefree: high / security: medium-high"] A --> E["Magic link
carefree: medium / security: medium"] A --> F["Passkey
carefree: high / security: high"] B --> B1["Depends on the carrier
change your number, lose access"] C --> C1["Password to remember
easy target for credential stuffing"] D --> D1["Bound to a big platform
the account isn't yours"] E --> E1["Bets on email timing
slow enough to make you doubt life"] F --> F1["Best experience
but device migration is the pain point"] style A fill:#1a1a2e,color:#fff style F fill:#16213e,color:#7fff7f

2. The essence of the hassle: every approach quietly collapses somewhere

Each approach above sounds okay, but they all have a collapse point hidden below the surface. Users don’t feel it day to day, but the moment they hit it, the experience drops to zero.

Hassle one: the phone number — the day you change it, your account becomes an orphan

The SMS code’s biggest vulnerability is that it welds your digital identity to a string of carrier digits.

Think of these real scenarios: you go abroad and your domestic number is suspended; you switch carriers and don’t keep the number; you change numbers and forget to re-bind dozens of apps one by one. When you one day want to log back into an old account, you find the number that receives the code is no longer yours — and many products don’t leave a recovery path for “change bound phone number” that doesn’t depend on the old phone.

Worse, on the security side: phone numbers get recycled and reassigned. The carrier gives your suspended number to someone else after a while, and the new owner can log into your former account with a single code. There’s also the SIM Swap attack — an attacker social-engineers the carrier into porting your number to their SIM, and every account you protect with SMS two-factor is instantly naked.

The SMS code looks convenient, but it essentially outsources account security to a carrier system you have no control over.

Hassle two: email — slow, easily lost, and nobody checks it daily

Email’s hassle is more hidden than the phone’s, but equally fatal.

First, the timing is absurdly bad. Registration waits for a verification email, password recovery waits for a link — a few seconds in theory, but possibly minutes in practice, or straight into the spam folder. In the products you’ve built, how many users dropped off stuck at “didn’t get the email”?

Second, email itself can be lost. A company email vanishes when you leave the job; a school email dies when you graduate; you forget the password of an old email and can’t get in. Once your account’s primary key is that email, losing the email means the account goes down with it.

Third, it’s a habits problem. In the mobile era, a good portion of users simply don’t check email anymore, especially domestic users. Asking them to “go to their inbox and click a confirmation link” is a complete break in the experience — they have to switch to another app, dig through emails, click the link, and switch back. Every extra step in this flow sheds another batch of people.

Hassle three: passwords — the human brain and security requirements are natural enemies

This is the oldest and most intractable of all the hassles: a secure password can’t be remembered, and a memorable password isn’t secure.

Security rules demand: use a different password for each site, make it long enough, mix upper/lowercase, digits, and symbols, and change it periodically. But the human brain can’t do this. So what actually happens in the real world:

  • Using the same password everywhere — so when one site is breached, you fall across the whole web (this is the breeding ground for “credential stuffing”);
  • Using passwords like Password123! that meet the rules but have no strength;
  • Writing passwords on sticky notes, notepads, memos — the security line physically collapses;
  • When you genuinely forget, you go through “password recovery” — and that path loops right back to the phone or email hassles.

The fundamental dilemma of passwords: they ask the human brain to do something it’s bad at — storing and managing many high-entropy random strings. By design, this is doomed to fail.

Strung together, these three hassles reveal a cruel truth — they actually pass the buck to each other:

graph TD
    A["Forgot password"] --> B["Go through recovery"]
    B --> C["Verify phone number"]
    C --> D["Phone number changed/suspended"]
    D --> E["Switch to email verification"]
    E --> F["Can't get into the email either"]
    F --> G["Contact human support"]
    G --> H["Prove you are you
extremely painful"] style A fill:#2d1b1b,color:#ff9999 style H fill:#2d1b1b,color:#ff5555

Every login approach’s “recovery” mechanism depends on another approach as a fallback. But once you lose both your phone and your email at the same time, the whole chain breaks, and you’re left with human support — to prove “you are you,” which is exactly the hardest and worst-experience link in any identity system.


3. A possible shakeup: is face login the answer?

Since passwords, phones, and email are all such hassles, many people’s first reaction is: just scan your face and be done with it, right?

It sounds lovely, but here we must clearly separate a key concept — there are two kinds of face scanning, and their security implications are worlds apart.

Type one: local biometrics. Like the iPhone’s Face ID. Your face never leaves your phone; it’s only compared inside the device’s secure chip, and the result is just “yes/no.” This is safe, and it’s exactly the basis of the Passkey experience — you think you’re “logging in by face,” but the face scan just unlocks the private key on your device.

Type two: server-side facial recognition. Your face is captured, sent to a server, and compared against faces in a database. This is very dangerous, for a simple reason:

If a password leaks, you can change it. If your face leaks, you can’t change it.

Biometrics are something irrevocable about you. Once a company’s face database is breached, the victims can never “reset” their faces for the rest of their lives. Add that liveness detection can be defeated by photos, videos, and deepfakes, and treating “the face” directly as a server-side login credential is manufacturing an irreversible disaster.

So the claim “scan your face to log in directly” is half right, half wrong:

  • The right part: using the face to locally unlock a key on the device — this is the future.
  • The wrong part: treating the face as a password uploaded to the server — this is a disaster.

Beyond face scanning, the shakeups truly reshaping the login landscape include these directions:

The full adoption of Passkeys. This is currently the most favored “endgame solution.” The FIDO Alliance, Apple, Google, and Microsoft are pushing it together. Its core idea: switch login entirely from “what you know” (a password) to “what you have” (your device + the private key inside it).

Passwordless becoming the default. More and more products no longer even offer a “set a password” option when new users register, going straight to codes or Passkeys. The password is degrading from a “must-have” to a “legacy item for compatibility with old users.”

Decentralized identity (DID). A more radical vision: your identity no longer belongs to any company but lives in a wallet you control, and you authorize with it to log into any service. The concept is advanced, but it’s far from large-scale adoption and currently stays more at the concept-and-small-experiment stage.

The diagram below is my read on the evolution path of login technology:

graph TD
    A["The password era
what you know"] --> B["SMS/email codes
weakening password dependence"] B --> C["Third-party login
outsourcing identity"] C --> D["The Passkey era
what you have"] D --> E["Decentralized identity
what you control"] A -.weakness.-> A1["stuffed/phished"] B -.weakness.-> B1["depends on carrier/email"] C -.weakness.-> C1["bound to a platform"] D -.strength.-> D1["phishing-resistant/passwordless"] E -.vision.-> E1["self-sovereign identity"] style A fill:#2d1b1b,color:#ff9999 style D fill:#16213e,color:#7fff7f style E fill:#1a1a2e,color:#9999ff

4. Best practices you can actually ship

After all this, down to brass tacks — if you had to design login for a new product today, how should you do it? Here’s a set of pragmatic, shippable, scenario-based recommendations — not theoretical perfection, but the engineering optimum.

Principle 1: Use a stable identifier as the account’s main body, not the phone number

This is the most important architectural decision. Don’t use the phone number or email directly as the user’s primary key.

The right approach: internally use a never-changing user_id (like a Snowflake ID or UUID) as the user’s unique identifier, and hang the phone number, email, third-party OpenID, etc. all under this user_id as bindable, unbindable, replaceable “login credentials.”

This way, a user changes their phone number? Just update one binding record, and the account itself is unharmed. This single design avoids 90% of the later “changed number, can’t recover account” complaints.

graph TD
    A["user_id
the permanent primary key"] --> B["Phone credential
re-bindable"] A --> C["Email credential
re-bindable"] A --> D["WeChat OpenID
unbindable"] A --> E["Passkey credential
multi-device"] A --> F["Password credential
optional/compat"] style A fill:#16213e,color:#7fff7f

Principle 2: Choose the primary login method by scenario

No single login method fits all products; choose by your actual scenario:

  • For domestic mass consumers: primarily push the SMS code, because of user habit and the highest conversion. But be sure to build the “re-bind phone number without depending on the old phone” recovery path.
  • For global / SaaS / developers: primarily push email + Passkey, supplemented with Google/GitHub third-party login.
  • For high-security needs (finance, enterprise internal): go straight to Passkey-primary + mandatory two-factor.
  • Inside mini-programs / the WeChat ecosystem: just use WeChat authorized login; don’t make users enter a phone number again.

Principle 3: Adopt Passkeys where you can, but keep a fallback path

Passkeys are the direction, and new products should offer them as the first choice. But there’s still a real pain point today: device migration and account recovery. The private key is on the device — what happens when you change or lose your phone?

So the shipping strategy is: make Passkey the mainstay, but always give users at least one independent recovery channel (a bound email, or a set of one-time recovery codes). Don’t make it a dead end where “lose the device and you’re permanently locked out.”

Principle 4: Never store plaintext passwords yourself

If your product does keep password login (for compatibility with old users), then burn one iron rule into your mind:

  • Never store plaintext, and never use fast hashes like MD5/SHA1;
  • Use slow hashing algorithms designed specifically for passwords — bcrypt / scrypt / Argon2 — salted and with tunable computation cost;
  • Judge password strength by entropy; stop torturing users with anti-human rules like “must contain upper/lowercase, digits, and symbols” — a sufficiently long passphrase is far safer than P@ss1!.

Principle 5: Balance security and experience — driven by risk

The last one is a mindset. Security and experience are a seesaw, but you don’t have to max out both every time. The smart approach is Risk-based Authentication:

  • The user logs in on a familiar device, familiar location, and usual time → fewer interruptions; even the code can be waived;
  • An anomaly is detected (new device, unusual location, late night, high-risk operation) → add verification, requiring a second confirmation.

Apply friction where it counts, rather than spreading it evenly over every user. This way you neither fail from being too lax nor drive normal users away by being too strict.


A closing note

The hassle of login ultimately comes down to the fact that it has to answer, at the same time, one of the most basic — and hardest — questions:

“How do you prove that you are you?”

Human society has taken thousands of years, evolving from seals, signatures, and ID cards all the way to today, and still hasn’t fully solved this question. Expecting software to nail it with a single login box was always wishful thinking.

But the direction is clear: we’re moving from the password era that “tests memory” to the key era that “tests possession.” The ideal future login should be — you don’t need to remember anything, don’t need to wait for any SMS or email, you only need to prove “this device is mine, this biometric is mine,” and leave the rest to cryptography.

As developers, what we can do is, along this evolution path, not dig for users the pits that could have been avoided: don’t weld the account to a phone number, don’t force users to remember anti-human passwords, don’t store other people’s faces in your own database, and don’t build a dead end where losing a device means eternal ruin.

Making the hassle of login “not a hassle” is itself a very advanced piece of engineering craftsmanship.