게으른 개발자의 끄적거림

토큰 넣는 방법 (Header vs 쿠키)

끄적잉 2024. 6. 26. 21:53
반응형

 

 웹 애플리케이션 개발에서 보안은 매우 중요한 요소입니다. 특히, 사용자 인증 및 권한 부여와 관련된 부분에서는 더욱 그러합니다. 토큰을 이용한 인증 방식은 최근 많이 사용되는 방법 중 하나인데, 이 토큰을 어떻게 전달하고 저장할 것인가는 중요한 설계 요소입니다. 여기에서는 토큰을 HTTP 헤더와 쿠키에 넣는 방법을 상세히 설명하고, 두 방법의 차이점을 깊이 있게 분석해 보겠습니다.

 


### HTTP 헤더에 토큰 넣기

#### 1. 개념 및 방법

HTTP 헤더에 토큰을 넣는 방식은 클라이언트가 서버에 요청을 보낼 때, 요청의 헤더 부분에 인증 토큰을 포함하는 방법입니다. 주로 사용되는 헤더는 `Authorization` 헤더입니다. 다음과 같은 형식을 사용합니다:

```
Authorization: Bearer <token>
```

여기서 `Bearer`는 인증 타입을 나타내며, 그 뒤에 토큰 값을 추가합니다.

 

 

반응형

 


#### 2. 구현 예시 (JavaScript, Express)

클라이언트 측 (JavaScript):

```javascript
const token = 'your-jwt-token';
fetch('https://api.example.com/secure-endpoint', {
    method: 'GET',
    headers: {
        'Authorization': `Bearer ${token}`
    }
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
```

 


서버 측 (Node.js, Express):

```javascript
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();

const verifyToken = (req, res, next) => {
    const authHeader = req.headers['authorization'];
    const token = authHeader && authHeader.split(' ')[1];
    if (token == null) return res.sendStatus(401);

    jwt.verify(token, 'your-secret-key', (err, user) => {
        if (err) return res.sendStatus(403);
        req.user = user;
        next();
    });
};

app.get('/secure-endpoint', verifyToken, (req, res) => {
    res.json({ message: 'Secure data' });
});

app.listen(3000, () => {
    console.log('Server running on port 3000');
});
```

 

 

 


### 쿠키에 토큰 넣기

#### 1. 개념 및 방법

쿠키를 사용하여 토큰을 저장하고 서버로 전송하는 방법은 웹 브라우저의 쿠키 기능을 활용하는 방식입니다. 쿠키는 클라이언트 측에 저장되며, 같은 도메인에서 발생하는 모든 HTTP 요청에 자동으로 포함됩니다. 쿠키에 저장된 토큰은 서버에서 읽어들여 인증을 수행할 수 있습니다.

쿠키는 HTTP-only 속성을 설정할 수 있어, 클라이언트 측 스크립트가 쿠키에 접근할 수 없도록 보호할 수 있습니다. 또한 `Secure` 속성을 설정하여 HTTPS를 통해서만 쿠키가 전송되도록 할 수 있습니다.

#### 2. 구현 예시 (JavaScript, Express)

클라이언트 측 (JavaScript):

```javascript
// 쿠키 설정
document.cookie = "token=your-jwt-token; Secure; HttpOnly; SameSite=Strict";

// 쿠키 읽기
const getCookie = (name) => {
    const value = `; ${document.cookie}`;
    const parts = value.split(`; ${name}=`);
    if (parts.length === 2) return parts.pop().split(';').shift();
    return null;
};
```

서버 측 (Node.js, Express):

```javascript
const express = require('express');
const jwt = require('jsonwebtoken');
const cookieParser = require('cookie-parser');
const app = express();

app.use(cookieParser());

const verifyToken = (req, res, next) => {
    const token = req.cookies.token;
    if (!token) return res.sendStatus(401);

    jwt.verify(token, 'your-secret-key', (err, user) => {
        if (err) return res.sendStatus(403);
        req.user = user;
        next();
    });
};

app.get('/secure-endpoint', verifyToken, (req, res) => {
    res.json({ message: 'Secure data' });
});

app.listen(3000, () => {
    console.log('Server running on port 3000');
});
```

 

 


### 두 방법의 차이점

#### 1. 보안성

- **HTTP 헤더 방식**: 토큰이 매 요청 시 `Authorization` 헤더에 포함되기 때문에 XSS(Cross-Site Scripting) 공격에 노출될 가능성이 상대적으로 적습니다. 이는 클라이언트 측 스크립트가 이 토큰에 접근하지 않기 때문입니다. 그러나, CSRF(Cross-Site Request Forgery) 공격에 취약할 수 있습니다.

- **쿠키 방식**: 쿠키에 `HttpOnly` 속성을 설정하면 클라이언트 측 스크립트가 쿠키에 접근할 수 없으므로 XSS 공격에 대한 방어가 가능합니다. 하지만, 쿠키는 자동으로 모든 요청에 포함되므로 CSRF 공격에 취약합니다. CSRF를 방지하기 위해서는 CSRF 토큰을 사용하거나 `SameSite` 속성을 적절히 설정해야 합니다.

 

 


#### 2. 사용 편의성

- **HTTP 헤더 방식**: 클라이언트 측에서 매 요청 시 헤더를 설정해야 합니다. 이는 클라이언트 측 코드가 조금 더 복잡해질 수 있음을 의미합니다. 또한, 브라우저 외의 클라이언트 (예: 모바일 앱)에서의 구현이 간단합니다.

- **쿠키 방식**: 쿠키는 브라우저가 자동으로 관리하므로 클라이언트 측 코드가 간단해집니다. 한 번 설정된 쿠키는 같은 도메인 내 모든 요청에 자동으로 포함되기 때문에 추가적인 설정이 필요 없습니다. 하지만, 브라우저 환경에 종속적이기 때문에 비브라우저 환경 (예: 모바일 앱)에서는 사용이 어려울 수 있습니다.

 

 


#### 3. 서버 설정 및 호환성

- **HTTP 헤더 방식**: 대부분의 서버 프레임워크에서 기본적으로 지원됩니다. 또한, CORS(Cross-Origin Resource Sharing) 설정에서 `Authorization` 헤더를 명시적으로 허용해야 할 수 있습니다.

- **쿠키 방식**: 쿠키는 HTTP 프로토콜의 기본 기능으로, 대부분의 서버 프레임워크에서 별도의 설정 없이 사용 가능합니다. 그러나 CORS 설정에서 쿠키를 허용하려면 추가적인 설정 (`credentials: true`)이 필요할 수 있습니다.

 

 

 

### 결론

HTTP 헤더와 쿠키에 토큰을 저장하고 전달하는 방식은 각각 장단점이 있습니다. HTTP 헤더 방식은 보안성이 높고, 비브라우저 환경에서도 쉽게 사용할 수 있지만, 클라이언트 측 코드가 복잡해질 수 있습니다. 쿠키 방식은 사용이 간편하고 브라우저 환경에서 자동으로 관리되지만, CSRF 공격에 취약할 수 있습니다. 따라서, 애플리케이션의 특성과 요구사항에 따라 적절한 방식을 선택하는 것이 중요합니다.

보안성을 최우선으로 고려해야 하는 경우, 각 방식의 취약점을 보완하는 추가적인 보안 조치를 병행하는 것이 좋습니다. 예를 들어, 쿠키 방식에서는 CSRF 토큰을 사용하거나 `SameSite` 속성을 적절히 설정하고, HTTP 헤더 방식에서는 CSRF 방어를 위한 추가적인 조치를 구현할 수 있습니다.

반응형