데이터베이스
This commit is contained in:
parent
c38e9b4a5b
commit
2d8bb456da
257
250818_gmail_tokens_database_setup.md
Normal file
257
250818_gmail_tokens_database_setup.md
Normal file
@ -0,0 +1,257 @@
|
||||
# Gmail Tokens 데이터베이스 구성
|
||||
|
||||
## 작성일: 2025-08-18
|
||||
## 작성자: Claude (with heejae)
|
||||
|
||||
---
|
||||
|
||||
## 1. 테이블 생성 정보
|
||||
|
||||
### 1.1 데이터베이스 접속 정보
|
||||
```bash
|
||||
Host: localhost
|
||||
Port: 5432
|
||||
Database: auth_db
|
||||
User: robeings
|
||||
Password: robeings
|
||||
```
|
||||
|
||||
### 1.2 생성된 테이블: `gmail_tokens`
|
||||
|
||||
```sql
|
||||
CREATE TABLE gmail_tokens (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id VARCHAR(100) UNIQUE NOT NULL,
|
||||
robing_id VARCHAR(50),
|
||||
token_data JSONB NOT NULL,
|
||||
oauth_config JSONB,
|
||||
scopes JSONB,
|
||||
metadata JSONB,
|
||||
expiry TIMESTAMP,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. JSONB 컬럼 구조
|
||||
|
||||
### 2.1 token_data (필수)
|
||||
```json
|
||||
{
|
||||
"access_token": "ya29.xxxx",
|
||||
"refresh_token": "1//xxxx",
|
||||
"token_type": "Bearer"
|
||||
}
|
||||
```
|
||||
|
||||
### 2.2 oauth_config
|
||||
```json
|
||||
{
|
||||
"client_id": "xxx.apps.googleusercontent.com",
|
||||
"client_secret": "GOCSPX-xxxx",
|
||||
"token_uri": "https://oauth2.googleapis.com/token",
|
||||
"auth_uri": "https://accounts.google.com/o/oauth2/auth"
|
||||
}
|
||||
```
|
||||
|
||||
### 2.3 scopes
|
||||
```json
|
||||
[
|
||||
"https://www.googleapis.com/auth/gmail.send",
|
||||
"https://www.googleapis.com/auth/gmail.readonly",
|
||||
"https://www.googleapis.com/auth/gmail.modify"
|
||||
]
|
||||
```
|
||||
|
||||
### 2.4 metadata
|
||||
```json
|
||||
{
|
||||
"email": "user@gmail.com",
|
||||
"display_name": "사용자명",
|
||||
"account_type": "gmail",
|
||||
"slack_user_id": "U091UNVE41M",
|
||||
"source_file": "original_filename.json",
|
||||
"imported_at": "2025-08-18"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 인덱스 구성
|
||||
|
||||
```sql
|
||||
-- 기본 인덱스
|
||||
CREATE INDEX idx_gmail_tokens_user_id ON gmail_tokens(user_id);
|
||||
CREATE INDEX idx_gmail_tokens_robing_id ON gmail_tokens(robing_id);
|
||||
|
||||
-- JSON 검색용 GIN 인덱스
|
||||
CREATE INDEX idx_gmail_tokens_token_data ON gmail_tokens USING GIN (token_data);
|
||||
CREATE INDEX idx_gmail_tokens_oauth_config ON gmail_tokens USING GIN (oauth_config);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 자동 업데이트 트리거
|
||||
|
||||
```sql
|
||||
-- updated_at 자동 갱신 함수
|
||||
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
NEW.updated_at = CURRENT_TIMESTAMP;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
-- 트리거 생성
|
||||
CREATE TRIGGER update_gmail_tokens_updated_at
|
||||
BEFORE UPDATE ON gmail_tokens
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION update_updated_at_column();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 마이그레이션 완료 데이터
|
||||
|
||||
### 5.1 원본 파일 위치
|
||||
```
|
||||
/home/admin/auth-server/tokens/
|
||||
├── heejae_gmail.json
|
||||
├── test_gmail.json
|
||||
└── unknown_gmail.json
|
||||
```
|
||||
|
||||
### 5.2 현재 저장된 데이터
|
||||
| user_id | robing_id | 권한 상태 | 이메일 발송 가능 |
|
||||
|---------|-----------|-----------|-----------------|
|
||||
| heejae | rb8001 | gmail.modify만 있음 | ❌ 불가능 |
|
||||
| test | rb8001 | gmail.send + modify | ✅ 가능 |
|
||||
| unknown | NULL | 프로필 권한만 | ❌ 불가능 |
|
||||
|
||||
### 5.3 권한 문제
|
||||
- **중요**: `gmail.modify`만으로는 이메일 발송 불가
|
||||
- 이메일 발송하려면 `gmail.send` 권한 필수
|
||||
- heejae 계정은 재인증 필요
|
||||
|
||||
---
|
||||
|
||||
## 6. 유용한 쿼리
|
||||
|
||||
### 6.1 토큰 조회
|
||||
```sql
|
||||
-- 특정 사용자 토큰 조회
|
||||
SELECT token_data->>'access_token' as access_token
|
||||
FROM gmail_tokens
|
||||
WHERE user_id = 'test';
|
||||
|
||||
-- 이메일 발송 가능한 사용자 찾기
|
||||
SELECT user_id, robing_id
|
||||
FROM gmail_tokens
|
||||
WHERE scopes @> '["https://www.googleapis.com/auth/gmail.send"]';
|
||||
```
|
||||
|
||||
### 6.2 토큰 업데이트
|
||||
```sql
|
||||
-- 액세스 토큰 갱신
|
||||
UPDATE gmail_tokens
|
||||
SET token_data = jsonb_set(
|
||||
token_data,
|
||||
'{access_token}',
|
||||
'"new_access_token"'
|
||||
)
|
||||
WHERE user_id = 'test';
|
||||
|
||||
-- 스코프 추가
|
||||
UPDATE gmail_tokens
|
||||
SET scopes = scopes || '["https://www.googleapis.com/auth/gmail.send"]'::jsonb
|
||||
WHERE user_id = 'heejae';
|
||||
```
|
||||
|
||||
### 6.3 메타데이터 활용
|
||||
```sql
|
||||
-- Slack 사용자와 매핑
|
||||
SELECT * FROM gmail_tokens
|
||||
WHERE metadata->>'slack_user_id' = 'U091UNVE41M';
|
||||
|
||||
-- 특정 로빙의 Gmail 계정 찾기
|
||||
SELECT user_id, metadata->>'email' as gmail_account
|
||||
FROM gmail_tokens
|
||||
WHERE robing_id = 'rb8001';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Python 연동 예시
|
||||
|
||||
```python
|
||||
import psycopg2
|
||||
import json
|
||||
from psycopg2.extras import RealDictCursor
|
||||
|
||||
# 연결
|
||||
conn = psycopg2.connect(
|
||||
host="localhost",
|
||||
database="auth_db",
|
||||
user="robeings",
|
||||
password="robeings"
|
||||
)
|
||||
|
||||
# 토큰 조회
|
||||
with conn.cursor(cursor_factory=RealDictCursor) as cur:
|
||||
cur.execute("""
|
||||
SELECT
|
||||
token_data->>'access_token' as access_token,
|
||||
token_data->>'refresh_token' as refresh_token,
|
||||
oauth_config,
|
||||
scopes
|
||||
FROM gmail_tokens
|
||||
WHERE user_id = %s
|
||||
""", ('test',))
|
||||
|
||||
token_info = cur.fetchone()
|
||||
|
||||
# Google OAuth 객체 생성에 사용
|
||||
credentials = {
|
||||
'token': token_info['access_token'],
|
||||
'refresh_token': token_info['refresh_token'],
|
||||
'client_id': token_info['oauth_config']['client_id'],
|
||||
'client_secret': token_info['oauth_config']['client_secret'],
|
||||
'scopes': token_info['scopes']
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 다음 단계 TODO
|
||||
|
||||
1. **권한 수정 필요**
|
||||
- heejae 계정에 `gmail.send` 권한 추가 (재인증 필요)
|
||||
- unknown 계정 용도 확인 및 권한 설정
|
||||
|
||||
2. **Slack 사용자 매핑**
|
||||
- metadata에 slack_user_id 추가
|
||||
- Slack User ID ↔ Gmail 계정 매핑 테이블 고려
|
||||
|
||||
3. **토큰 자동 갱신**
|
||||
- refresh_token 사용한 자동 갱신 로직 구현
|
||||
- expiry 필드 활용한 만료 체크
|
||||
|
||||
4. **보안 강화**
|
||||
- 토큰 암호화 고려
|
||||
- 접근 로그 테이블 추가
|
||||
|
||||
5. **skill-email 서비스 수정**
|
||||
- 파일 기반 → DB 기반 토큰 조회로 변경
|
||||
- PostgreSQL 연결 설정 추가
|
||||
|
||||
---
|
||||
|
||||
## 9. 참고사항
|
||||
|
||||
- JSONB 타입 사용으로 유연한 스키마 확장 가능
|
||||
- GIN 인덱스로 JSON 내부 검색 성능 최적화
|
||||
- 트리거로 updated_at 자동 관리
|
||||
- 모든 토큰 정보가 중앙 집중식으로 관리됨
|
||||
Loading…
x
Reference in New Issue
Block a user