OAuth 2.0 ve JWT ile Authentication

Teknoloji 📖 3 dk okuma
#web#design#kariyer

OAuth 2.0 ve JWT, modern web uygulamalarında authentication standardıdır.

JWT (JSON Web Token)

Structure

header.payload.signature

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Node.js Implementation

const jwt = require('jsonwebtoken');

// Token oluştur
function generateToken(user) {
  return jwt.sign(
    { 
      id: user.id, 
      email: user.email,
      role: user.role 
    },
    process.env.JWT_SECRET,
    { expiresIn: '7d' }
  );
}

// Token doğrula
function verifyToken(token) {
  try {
    return jwt.verify(token, process.env.JWT_SECRET);
  } catch (err) {
    throw new Error('Invalid token');
  }
}

// Middleware
function authenticate(req, res, next) {
  const token = req.headers.authorization?.split(' ')[1];
  
  if (!token) {
    return res.status(401).json({ error: 'No token provided' });
  }
  
  try {
    req.user = verifyToken(token);
    next();
  } catch (err) {
    return res.status(401).json({ error: 'Invalid token' });
  }
}

OAuth 2.0 Flow

Authorization Code Flow

// 1. Redirect to OAuth provider
app.get('/auth/google', (req, res) => {
  const authUrl = `https://accounts.google.com/o/oauth2/v2/auth?` +
    `client_id=${CLIENT_ID}&` +
    `redirect_uri=${REDIRECT_URI}&` +
    `response_type=code&` +
    `scope=openid email profile`;
  
  res.redirect(authUrl);
});

// 2. Callback endpoint
app.get('/auth/callback', async (req, res) => {
  const { code } = req.query;
  
  // Exchange code for token
  const tokenResponse = await fetch('https://oauth2.googleapis.com/token', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      code,
      client_id: CLIENT_ID,
      client_secret: CLIENT_SECRET,
      redirect_uri: REDIRECT_URI,
      grant_type: 'authorization_code'
    })
  });
  
  const { access_token, id_token } = await tokenResponse.json();
  
  // Get user info
  const userResponse = await fetch('https://www.googleapis.com/oauth2/v2/userinfo', {
    headers: { Authorization: `Bearer ${access_token}` }
  });
  
  const user = await userResponse.json();
  
  // Create JWT for your app
  const appToken = generateToken(user);
  
  res.json({ token: appToken });
});

Refresh Token Pattern

// Login
app.post('/login', async (req, res) => {
  const user = await authenticateUser(req.body);
  
  const accessToken = generateToken(user, '15m');
  const refreshToken = generateToken(user, '7d');
  
  // Store refresh token in database
  await saveRefreshToken(user.id, refreshToken);
  
  res.json({ accessToken, refreshToken });
});

// Refresh endpoint
app.post('/refresh', async (req, res) => {
  const { refreshToken } = req.body;
  
  try {
    const payload = verifyToken(refreshToken);
    const isValid = await validateRefreshToken(payload.id, refreshToken);
    
    if (!isValid) throw new Error('Invalid refresh token');
    
    const newAccessToken = generateToken(payload, '15m');
    res.json({ accessToken: newAccessToken });
  } catch (err) {
    res.status(401).json({ error: 'Refresh token expired' });
  }
});

Best Practices

1. Secure Storage

// ❌ localStorage (XSS vulnerable)
localStorage.setItem('token', token);

// ✅ HttpOnly cookie
res.cookie('token', token, {
  httpOnly: true,
  secure: true,
  sameSite: 'strict',
  maxAge: 7 * 24 * 60 * 60 * 1000
});

2. CSRF Protection

const csrf = require('csurf');
app.use(csrf({ cookie: true }));

3. Rate Limiting

const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 100
});

app.use('/api/', limiter);

Güvenli authentication sistemleri kurun!