관리 메뉴

Mini

[Http] http req에서 userId 얻는법 본문

CS/HTTP

[Http] http req에서 userId 얻는법

Mini_96 2024. 8. 28. 01:52

HTTP 요청에서 user ID를 얻는 방법은 인증 메커니즘에 따라 다양할 수 있습니다. 일반적으로 사용되는 몇 가지 방법을 소개해 드리겠습니다:

  1. JWT (JSON Web Token) 사용:
    JWT는 가장 흔히 사용되는 방법 중 하나입니다. 클라이언트가 로그인하면 서버는 JWT를 발급하고, 이후의 요청에서 클라이언트는 이 토큰을 함께 보냅니다.
const jwt = require('jsonwebtoken');

// 미들웨어 함수
function authenticateToken(req, res, next) {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1];

  if (token == null) return res.sendStatus(401);

  jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
    if (err) return res.sendStatus(403);
    req.user = user;
    next();
  });
}

// 라우터에서 사용
app.post('/api/cards', authenticateToken, (req, res) => {
  const userId = req.user.id;
  // ... 나머지 로직
});
  1. 세션 사용:
    Express-session과 같은 라이브러리를 사용하여 서버 측 세션을 관리할 수 있습니다.
const session = require('express-session');

app.use(session({
  secret: 'your secret key',
  resave: false,
  saveUninitialized: true,
  cookie: { secure: true }
}));

// 로그인 라우트
app.post('/login', (req, res) => {
  // 사용자 인증 로직
  req.session.userId = user.id;
  res.send('Logged in');
});

// 보호된 라우트
app.post('/api/cards', (req, res) => {
  const userId = req.session.userId;
  if (!userId) {
    return res.status(401).send('Unauthorized');
  }
  // ... 나머지 로직
});
  1. API Key 사용:
    클라이언트가 고유한 API 키를 헤더에 포함시켜 보내는 방식입니다.
function validateApiKey(req, res, next) {
  const apiKey = req.headers['x-api-key'];
  if (!apiKey) {
    return res.status(401).send('API Key required');
  }

  // API 키로 사용자 ID 조회
  getUserIdByApiKey(apiKey)
    .then(userId => {
      if (!userId) {
        return res.status(401).send('Invalid API Key');
      }
      req.userId = userId;
      next();
    })
    .catch(err => res.status(500).send('Server error'));
}

app.post('/api/cards', validateApiKey, (req, res) => {
  const userId = req.userId;
  // ... 나머지 로직
});
  1. OAuth 2.0:
    외부 서비스(예: Google, Facebook)를 통한 인증을 사용할 수 있습니다. 이 경우 액세스 토큰을 통해 사용자 정보를 얻습니다.
const passport = require('passport');
const GoogleStrategy = require('passport-google-oauth20').Strategy;

passport.use(new GoogleStrategy({
    clientID: GOOGLE_CLIENT_ID,
    clientSecret: GOOGLE_CLIENT_SECRET,
    callbackURL: "http://www.example.com/auth/google/callback"
  },
  function(accessToken, refreshToken, profile, cb) {
    // profile.id를 사용하여 사용자 찾기 또는 생성
  }
));

app.get('/auth/google',
  passport.authenticate('google', { scope: ['profile'] }));

app.get('/auth/google/callback', 
  passport.authenticate('google', { failureRedirect: '/login' }),
  function(req, res) {
    // 성공적인 인증, 리다이렉트
    res.redirect('/');
  });

// 보호된 라우트
app.post('/api/cards', (req, res) => {
  const userId = req.user.id;  // Passport가 req.user를 설정
  // ... 나머지 로직
});

Best Practices:

  1. HTTPS 사용: 모든 인증 관련 통신은 HTTPS를 통해 이루어져야 합니다.
  2. 토큰 만료: JWT나 세션에 적절한 만료 시간을 설정하세요.
  3. 보안 헤더: Helmet과 같은 미들웨어를 사용하여 보안 관련 HTTP 헤더를 설정하세요.
  4. 에러 처리: 인증 실패 시 적절한 에러 메시지를 반환하되, 너무 자세한 정보는 노출하지 마세요.
  5. 로깅: 인증 관련 이벤트를 로깅하여 보안 모니터링에 활용하세요.

이러한 방법들 중 프로젝트의 요구사항과 보안 정책에 가장 적합한 것을 선택하여 사용하시면 됩니다. 대부분의 경우 JWT나 세션 기반 인증이 널리 사용되며, 특히 JWT는 확장성이 좋고 stateless하여 많이 선호됩니다.