0. ๋ค์ด๊ฐ๋ฉฐ...
ํ์ฌ ์งํํ๊ณ ์๋ ๊ตฌ๋ฆ PROTECT
์์ ๊ตฌํํ API์ ๋ํ ์ฑ๋ฅํ
์คํธ๋ฅผ ํ๊ณ ์๋ค. ํ์๋ ์ง์ ํ ๋๋์ ์ฑ๋ฅ ํ
์คํธ
๋ฅผ ์ํด์๋ ๋งค๋ฒ ๋ค๋ฅธ JWT ํ ํฐ ๊ฐ์ด Header์ ๋ด๊ฒจ์ผ ํ๋ค๊ณ ์๊ฐํ๋ค. ์ด์ ๋ ๋ค์๊ณผ ๊ฐ๋ค.
- ์ค์ ์ ๊ฐ์ ํ๊ฒฝ์ ์ต๋ํ ๊ตฌํํ ์ ์๋ค. ์ค์ ์๋น์ค์์๋, ๋ค๋ฅธ ์ฌ์ฉ์๋ ํ ๋ช ๋ ์ฌ์ฉํ์ง ์๋๋ฐ, ํ ์ฌ๋๋ง ์์ฒญ์ 5๋ง ๋ฒ ํ๋ ๊ฒฝ์ฐ๋ ๊ทนํ ๋๋ฌผ ๊ฒ์ด๋ค.
- ํ ์ฌ๋์ด ๋งค๋ฒ ๊ฐ์ ์์ฒญ์ ํ ๊ฒฝ์ฐ, DB ์บ์ฑ๊ณผ ์๋ฒ ์บ์ฑ์ผ๋ก ํด๋น ๋ด์ฉ์ด ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅ๋ ๊ฒ์ด๋ฏ๋ก, ์ง์ ํ ์๋ฒ์ ์ฑ๋ฅ์ ๋ณผ ์ ์์ ๊ฒ์ด๋ผ ํ๋จํ๋ค.
๋ฐ๋ผ์ ์ฌ๋ฌ ๋ช
์ด ์๋น์ค๋ฅผ ๊ฐ์ ์ฌ์ฉํ๊ณ ์๋ ๊ฒ์ ํ๋ด๋ด๊ณ ์ HEADER์ Authorization
์ ๋งค ๋ฒ ๋ค๋ฅธ ํ ํฐ ๊ฐ์ ๋ฃ์๋ค.
1. ํ ํฐ ์์ฑ ์ค๋น ํ๊ธฐ
์ฐ๋ฆฌ ํ์ ํ์๊ฐ์
๋ฐ ๋ก๊ทธ์ธ์ KAKAO OAUTH2
๋ก ๋์ด ์๊ธฐ์, ๋๋์ ํ ํฐ์ ์นด์นด์ค ๋ก๊ทธ์ธ ๋ฃจํธ๋ก ๊ฐ์ ธ์ค๋ ๊ฒ์ ํ๋ค์๋ค. ๋ฐ๋ผ์ ๊ฐ๋ฐ์์ฉ ํ ํฐ ์์ฑ๊ธฐ API๋ฅผ ํ๋ ๋ง๋ค์๋ค.
์ด์ ์ฌ๊ธฐ์ member_id๋ฅผ ๋ฃ๊ณ , ํ ํฐ์ ๋ฐ์ผ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๋์ค๋๋ฐ, ์ด JSON ์ค์์ accessToken
์ ํ์ฑํ์ฌ ๊บผ๋ด์, ํ ์ค์ jwt ํ ํฐ ํ๋๊ฐ ์ ํ csv ํ์ผ์ ๋ง๋ค์ด ๋ณด๋ ค๊ณ ํ๋ค.
2. ํ ํฐ ์ถ์ถ ๋ฐ ์์ง๊ธฐ (python)
import argparse
import csv
import requests
from concurrent.futures import ThreadPoolExecutor, as_completed
def fetch_token(i):
try:
url = f'http://{api ์ฃผ์}/api/member/developer-get-token?id={i}'
response = requests.get(url, timeout=3)
if response.status_code == 200:
result = response.json()
if result.get('status') == 'success':
print(f"[{i}] ์ ์ฅ ์ฑ๊ณต")
return result['data']['accessToken']
else:
print(f"[{i}] ์คํจ: {result.get('message')}")
else:
print(f"[{i}] HTTP ์ค๋ฅ: {response.status_code}")
except Exception as e:
print(f"[{i}] ์์ธ ๋ฐ์: {e}")
return None
def collect_tokens(start_id, end_id, output_file, max_workers=10):
with open(output_file, mode='w', newline='') as file:
writer = csv.writer(file)
with ThreadPoolExecutor(max_workers=max_workers) as executor:
futures = {executor.submit(fetch_token, i): i for i in range(start_id, end_id + 1)}
for future in as_completed(futures):
token = future.result()
if token:
writer.writerow([token])
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='accessToken ์์ง๊ธฐ')
parser.add_argument('--start', type=int, required=True, help='์์ ID')
parser.add_argument('--end', type=int, required=True, help='๋ ID')
parser.add_argument('--output', type=str, default='tokens.csv', help='์ ์ฅํ CSV ํ์ผ๋ช
')
parser.add_argument('--workers', type=int, default=50, help='์ต๋ ๋์ ์์ฒญ ์')
args = parser.parse_args()
collect_tokens(args.start, args.end, args.output, args.workers)
์๊น ๋ฐ์๋ json ์๋ต ์ค accessToken
์ ํ์ฑ ํ ๊บผ๋ด์ tokens.csv ๋ผ๋ ํ์ผ์ ํ ์ค์ฉ ์ ๋๋ค. ์ด๊ฑธ ๊ทธ๋ฅ ์คํํ๋ฉด, ํ๋์ ์ฐ๋ ๋๊ฐ ๋ชจ๋ ์์
์ ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์ ๋๋ฆฌ๋ค. ๋ฐ๋ผ์ ThreadPoolExecutor
๋ฅผ ํ์ฉํด ๋ณ๋ ฌ์ ์์
์ผ๋ก ์ฒ๋ฆฌํ์๋ค. PYTHON์ ๊ฒฝ์ฐ, GIL(Global Interpreter Lock)์ผ๋ก ์ธํด, ๋์์ ์ฌ๋ฌ ์ค๋ ๋๊ฐ Python ์ฝ๋๋ฅผ ์คํํ์ง ๋ชปํ์ง๋ง ์์ธ์ ์ผ๋ก I/O ์์
(API ์์ฒญ, ํ์ผ ์ฝ๊ธฐ, ๋คํธ์ํฌ)์๋ GIL์ด ์ ์ ํ๋ ค์ ๋ณ๋ ฌ ์ฐ๋ ๋ ์์
์ด ๊ฐ๋ฅํ๋ค.
# ThreadPool ์ด์ฉํ ๋ฉํฐ ์ค๋ ๋ ์์
with ThreadPoolExecutor(max_workers=max_workers) as executor:
futures = {executor.submit(fetch_token, i): i for i in range(start_id, end_id + 1)}
for future in as_completed(futures):
token = future.result()
if token:
writer.writerow([token])
์ด๋ฅผ ์คํํ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ํ์ผ ๋ฐ์ token ํ์ผ์ด ์๊ธด๋ค.