Google OAuth — Passport bilan

~20 daq · Express · Autentifikatsiya va Xavfsizlik

OAuth nima?

Foydalanuvchi "Google bilan kirish" tugmasini bosadi. Nima bo'ladi?

Siz Google ga parolni bermaysiz — Google o'zi tekshiradi. Google sizga faqat "bu foydalanuvchi kim" degan ma'lumotni beradi. Bu — OAuth.

Hayotiy o'xshatma: mehmonxonaga keldingiz. Pasportingizni ko'rsatasiz — mehmonxona xodimi pasportni o'qiydi, lekin saqlamaydi. Faqat "bu kishi kim" degan ma'lumotni oladi. Pasportingiz sizda qoladi.

OAuth da Google — pasport beruvchi davlat. Sizning ilovangiz — mehmonxona. Foydalanuvchi — mehmon.


Google Console da sozlash

Kod yozishdan oldin Google Console da loyiha yaratish kerak:

  1. console.cloud.google.com ga kiring
  2. Yangi loyiha yarating
  3. "APIs & Services" → "Credentials" → "Create Credentials" → "OAuth 2.0 Client ID"
  4. Application type: "Web application"
  5. Authorized redirect URIs: http://localhost:3000/auth/google/callback
  6. Client ID va Client Secret ni oling — .env ga saqlang
npm install passport-google-oauth20

Strategiya sozlash

const GoogleStrategy = require('passport-google-oauth20').Strategy;

passport.use(new GoogleStrategy(
  {
    clientID:     process.env.GOOGLE_CLIENT_ID,
    clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    callbackURL:  '/auth/google/callback',
  },
  async (accessToken, refreshToken, profile, done) => {
    // profile — Google dan kelgan foydalanuvchi ma'lumoti
    try {
      const email = profile.emails[0].value;
      const name  = profile.displayName;

      // Foydalanuvchi allaqachon ro'yxatdan o'tganmi?
      let result = await pool.query('SELECT * FROM users WHERE google_id = $1', [profile.id]);

      if (result.rows.length > 0) {
        return done(null, result.rows[0]); // mavjud foydalanuvchi
      }

      // Yangi foydalanuvchi — yaratish
      result = await pool.query(
        'INSERT INTO users (name, email, google_id) VALUES ($1, $2, $3) RETURNING *',
        [name, email, profile.id]
      );

      return done(null, result.rows[0]);
    } catch (err) {
      return done(err);
    }
  }
));

profile — Google dan kelgan ma'lumot: profile.id (Google ID), profile.displayName (ism), profile.emails[0].value (email).


Route lar

// 1. Foydalanuvchini Google ga yo'naltirish
router.get('/auth/google',
  passport.authenticate('google', { scope: ['profile', 'email'] })
);

// 2. Google qaytib kelganda
router.get('/auth/google/callback',
  passport.authenticate('google', { session: false, failureRedirect: '/login' }),
  (req, res) => {
    // Muvaffaqiyatli — JWT yaratib frontendga yuborish
    const token = jwt.sign(
      { userId: req.user.id, role: req.user.role },
      process.env.JWT_SECRET,
      { expiresIn: '15m' }
    );

    // Frontend ga token bilan yo'naltirish
    res.redirect(`${process.env.FRONTEND_URL}/auth/callback?token=${token}`);
  }
);

Jarayon qanday ishlaydi:

Foydalanuvchi /auth/google ga boradi
    ↓
Express → Google login sahifasiga yo'naltiradi
    ↓
Foydalanuvchi Google da login qiladi
    ↓
Google → /auth/google/callback ga qaytaradi
    ↓
Passport strategiya ishlaydi — foydalanuvchi topiladi/yaratiladi
    ↓
JWT yaratiladi, frontend ga yuboriladi

scope nima?

scope: ['profile', 'email'] — Google dan qanday ma'lumot so'ralishi. profile — ism, rasm. email — email manzil. Foydalanuvchi login qilganda Google "bu ilova sizning profilingiz va emailingizni ko'rmoqchi" deb so'raydi.

Faqat kerakli ma'lumotlar so'raladi — bu yaxshi amaliyot.


Ma'lumotlar bazasi jadval

ALTER TABLE users ADD COLUMN google_id VARCHAR(255) UNIQUE;
ALTER TABLE users ALTER COLUMN password_hash DROP NOT NULL;
-- Google bilan kirgan foydalanuvchining paroli bo'lmaydi

Tez-tez uchraydigan xatolar

Redirect URI mos kelmasa:

Error: redirect_uri_mismatch

Google Console da yozilgan redirect URI va kodda yozilgan bir xil bo'lishi kerak. http va https, localhost:3000 va localhost:3001 — farq qiladi.

scope ni unutish:

passport.authenticate('google') // scope yo'q — email kelmaydi
passport.authenticate('google', { scope: ['profile', 'email'] }) // to'g'ri

Xulosa

OAuth — foydalanuvchi parolini bermaydi, Google o'zi tekshiradi va "bu kim" degan ma'lumotni beradi.

Google Console da Client ID va Secret olinadi. Strategiya foydalanuvchini Google ID bo'yicha topadi yoki yangi yaratadi. Muvaffaqiyatli bo'lgach JWT yaratiladi.


Keyingi dars

24-dars: Session — express-session, cookie-session