I remember looking at the login page of a large project a year ago and thinking, "God, how does it all work?" Four buttons to log in, some tokens, redirects... My head was spinning. Today we will sort everything out so that you don't drown in this sea of technology.

Why authorization is not just "enter password" 🔐
In 2026, users want to log in to apps quickly, safely, and without a headache. Some prefer the classic email and password, others prefer a single "Sign in with Google" button, and others want to receive a code in an SMS and not bother with passwords.
Your task as a developer is to give them all this, and in such a way that the system is safe and does not turn into a spaghetti code 🍝
Let's start with the basics that every junior should understand, and then we'll move on.
Email/password: the old school that hasn't gone anywhere ✉️
Classic authorization via email and password is the foundation. Yes, many say that it is outdated, but the truth is that it is still used by millions of services. And knowing how it works correctly is critical.
What happens when you register
The user enters an email and password. Your first task is validation. The email must be real (at least syntactically correct), and the password must be sufficiently complex.
In 2026, the minimum is 8 characters, letters of different cases, numbers, and special characters. But the requirements depend on the project — not everywhere you need a "password like a bank safe".
And the most important thing: never, you hear me, NEVER do not store passwords in plain text. You must hash the password before saving it to the database. In 2026, the standard is bcrypt or Argon2.
// Example with bcrypt (Node.js)
const bcrypt = require('bcrypt');
// When registering
const saltRounds = 10;
const hashedPassword = await bcrypt.hash(userPassword, saltRounds);
// Saving hashedPassword to the database
// At the entrance
const isValid = await bcrypt.compare(userPassword, hashedPasswordFromDB);
if (isValid) {
// User is authorized
}What happens when you log in
The user enters an email and password. You search for this email in the database, get the password hash and compare it with the entered password via bcrypt.compare. If it matches, generate a token (usually JWT) and give it to the client.
JWT is your new best friend 🤝
JSON Web Token is a string that contains encrypted user information. After successful authorization, you create a JWT with user data (id, email, role) and send it to the client. The client saves the token and sends it with each request to the API.
const jwt = require('jsonwebtoken');
// Token creation
const token = jwt.sign(
{ userId: user.id, email: user.email },
process.env.JWT_SECRET,
{ expiresIn: '7d' }
);
// Token verification
const decoded = jwt.verify(token, process.env.JWT_SECRET);Refresh tokens: when the access token has expired 🧊
The access token usually does not last long — from 15 minutes to several hours. When it expires, the user does not have to re-enter the password. To do this, use a refresh token — a long-lived token that is stored in a safe place (usually httpOnly cookie) and is used to obtain a new access token.
The logic is simple: short token for work, long token to update the short one. You will find this pattern in most real projects.

OAuth 2.0: “Sign in with Google” and all that magic ✨
When a user clicks "Sign in with Google" or "Sign in with Apple", an OAuth 2.0 dance takes place behind the scenes. This is a standard that allows third-party services to authorize users without transferring a password.
How it works in a nutshell
User clicks "Sign in with Google"
You redirect it to the Google page
User logs in and gives permission
Google redirects back to your site with a temporary code
You are changing code to the token and get user data
What a junior needs to know
You need to register the application in the console (Google/Apple) and get Client ID and Client Secret.
The most popular scenario is Authorization Code Flow.
Do not lose the state between redirects — use the
stateparameter (CSRF protection).Client Secret should never get to the frontend.
// Example with Passport.js (Node.js)
const passport = require('passport');
const GoogleStrategy = require('passport-google-oauth20').Strategy;
passport.use(new GoogleStrategy({
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: "http://localhost:3000/auth/google/callback"
},
async (accessToken, refreshToken, profile, done) => {
// Here you get user data
// Looking for it in your database or creating a new one
const user = await findOrCreateUser(profile);
return done(null, user);
}
));Apple Sign In: features 🍏
Apple takes privacy seriously. They can hide the user's real email and give a proxy email of the form randomstring@privaterelay.appleid.com. Plus, they have their own specifics with the generation of client_secret — it is created programmatically, and not just issued in the console.
Main rakes: incorrect redirect_uri (must match 1 in 1), missing state, “user cancelled” not processed, and Client Secret leak to the front.
OTP: one-time passwords and SMS codes 📲
One-Time Password is a code that lives for a few minutes and is used once. In 2026, this is one of the most popular ways to authorize, especially in mobile applications.
How it works
User enters phone number
You generate a code (4–6 digits), save it with TTL (often in Redis)
You are sending the code via SMS gateway
User enters code → you check → you create a session
// OTP generation
function generateOTP(length = 6) {
const digits = '0123456789';
let otp = '';
for (let i = 0; i < length; i++) {
otp += digits[Math.floor(Math.random() * 10)];
}
return otp;
}
// Saving with TTL (Redis)
await redis.setex(`otp:${phoneNumber}`, 300, otp); // 5 minutes
// Sending SMS
await smsService.send(phoneNumber, `Your code: ${otp}`);
// Verification
const storedOTP = await redis.get(`otp:${phoneNumber}`);
if (storedOTP === userInputOTP) {
// Authorization successful
await redis.del(`otp:${phoneNumber}`);
}TOTP: when SMS is not an option ⏱️
Time-based One-Time Password — codes that are generated by applications such as Google Authenticator or Authy. It works on the basis of a secret key and time. A great option for 2FA.
const speakeasy = require('speakeasy');
// Secret generation
const secret = speakeasy.generateSecret({ name: 'MyApp (user@email.com)' });
// secret.base32 is what you need to save in the database
// Code verification
const verified = speakeasy.totp.verify({
secret: secret.base32,
encoding: 'base32',
token: userInputCode,
window: 2 // time desynchronization tolerance
});OTP security
Limit the number of input attempts (usually 3–5)
Use rate limiting (no more than N SMS per number per hour)
Make the codes long enough (at least 6 digits)
Be sure to set TTL (5–10 minutes)
The "authorization map" illustration will work well here — to visually collect everything in one picture: email/password → JWT → refresh → OAuth → OTP.
What a junior should know: a checklist for an interview 🧠
Basic things
The difference between authentication and authorization
What is JWT and what parts does it consist of (Header, Payload, Signature)
Why you shouldn't store passwords in plain text
What is salt in password hashing
Intermediate level
Access token vs refresh token
How OAuth 2.0 works at a high level
What is CSRF and protection through state/token/origin
Where to store tokens on the front and why (httpOnly cookies / memory / localStorage)
Advanced level
Logout with JWT (blacklist in Redis or short TTL)
PKCE in OAuth and why it is needed
Protection against brute force with OTP (rate limiting, backoff, captcha)
In 2026, it's no longer rocket science 🚀
Even 5-10 years ago, OAuth seemed inaccessible. Now it is a standard that is built into all normal frameworks. Libraries do 80% of the work, and you need to understand the concepts and be able to put everything together correctly.
Start with the basics — email/password and JWT. Then add OAuth. And if necessary, OTP for convenience or additional security. Always remember the minimum: hash passwords, check tokens, limit login attempts, use HTTPS.
All this and much more can be learned in the Codex 🎓
If after reading this article you have any questions (and they definitely appeared - authorization is a deep topic), come to Code.
Kodik — programming training with a focus on practice: we analyze topics in detail, with live code examples and explanations of pitfalls. Not "here's the code, copy it", but an understanding of how and why everything works.
Practical tasks: you will collect authorization from scratch — from email/password to OAuth and 2FA
Reinforcing skills through exercises and mini-projects
Analysis of typical errors and patterns from real applications
Need support? There is a community 👥
We have active Telegram channel, where more than 2000 developers are sitting. You can ask a question, discuss a problem, ask for a code review, or just chat with people on the same path.
Join Kodik — we will analyze the authorization so that you can explain it to others with your eyes closed 😉
