๊ตฌ๊ธ OAuth ์ค์
6. ๋ค์ํ ์์ ๋ก๊ทธ์ธ ์ ๊ณต์์ ์ฐ๋ํ๊ธฐ
์์ ๋ก๊ทธ์ธ์ ์ ๊ณตํ๋ ์ฃผ์ ์ ๊ณต์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ๊ฐ ํ๋ซํผ์ OAuth 2.0 ํ์ค ์ ๋ฐ๋ฅด์ง๋ง, ๊ตฌ์ฑ๊ณผ ์ฌ์ฉ ๋ฐฉ๋ฒ ์ ์ฝ๊ฐ์ ์ฐจ์ด๊ฐ ์์ต๋๋ค.
1. ๊ตฌ๊ธ OAuth 2.0
- ์ฌ์ฉ์ ์ ๋ณด : ์ด๋ฉ์ผ, ํ๋กํ ์ฌ์ง, ์ด๋ฆ ๋ฑ
- ์ฌ์ฉ ์์ : Google Drive ๋๋ Gmail API์ ํตํฉ
2. ํ์ด์ค๋ถ OAuth 2.0
- ์ฌ์ฉ์ ์ ๋ณด : ํ๋กํ ์ ๋ณด, ์น๊ตฌ ๋ชฉ๋ก, ํ์ด์ง ์ ๋ณด ๋ฑ
- ์ฌ์ฉ ์์ : ํ์ด์ค๋ถ ํ์ด์ง ๊ด๋ฆฌ ๋๋ ๋ง์ผํ ๋๊ตฌ ์ฐ๋
ํ์ด์ค๋ถ ๊ฐ๋ฐ์ ๋ฌธ์๐
3. ์นด์นด์ค OAuth 2.0
- ์ฌ์ฉ์ ์ ๋ณด : ์นด์นด์คํก ํ๋กํ, ์ด๋ฉ์ผ, ์น๊ตฌ ๋ชฉ๋ก ๋ฑ
- ์ฌ์ฉ ์์ : ์นด์นด์คํก ๋ก๊ทธ์ธ๊ณผ ๋ฉ์์ง API ํ์ฉ
์นด์นด์ค ๊ฐ๋ฐ์ ๋ฌธ์๐
7. ๋ค์ค ์ ๊ณต์ ๋ก๊ทธ์ธ ๊ตฌํ ์์
์๋๋ Flask ๋ฅผ ์ฌ์ฉํด ๊ตฌ๊ธ๊ณผ ์นด์นด์ค์ OAuth ๋ก๊ทธ์ธ ๋ฒํผ ์ ๋์์ ์ ๊ณตํ๋ ์์ ์ ๋๋ค.
์์ ์ฝ๋: Flask์ ๋ค์ค ์์ ๋ก๊ทธ์ธ
from flask import Flask, redirect, request, session, url_for
import requests
app = Flask(__name__)
app.secret_key = 'your_secret_key'
# ๊ตฌ๊ธ OAuth ์ค์
GOOGLE_CLIENT_ID = 'your_google_client_id'
GOOGLE_CLIENT_SECRET = 'your_google_client_secret'
GOOGLE_REDIRECT_URI = 'http://localhost:5000/google/callback'
# ์นด์นด์ค OAuth ์ค์
KAKAO_CLIENT_ID = 'your_kakao_client_id'
KAKAO_REDIRECT_URI = 'http://localhost:5000/kakao/callback'
@app.route('/')
def home():
return '''
<a href="/login/google">๊ตฌ๊ธ ๋ก๊ทธ์ธ</a><br>
<a href="/login/kakao">์นด์นด์ค ๋ก๊ทธ์ธ</a>
'''
@app.route('/login/google')
def login_google():
google_auth_url = (
f"https://accounts.google.com/o/oauth2/auth?response_type=code"
f"&client_id={GOOGLE_CLIENT_ID}&redirect_uri={GOOGLE_REDIRECT_URI}&scope=email"
)
return redirect(google_auth_url)
@app.route('/google/callback')
def google_callback():
code = request.args.get('code')
token_response = requests.post('https://oauth2.googleapis.com/token', data={
'code': code,
'client_id': GOOGLE_CLIENT_ID,
'client_secret': GOOGLE_CLIENT_SECRET,
'redirect_uri': GOOGLE_REDIRECT_URI,
'grant_type': 'authorization_code'
}).json()
access_token = token_response['access_token']
user_info = requests.get('https://www.googleapis.com/oauth2/v1/userinfo', headers={
'Authorization': f'Bearer {access_token}'
}).json()
return f"๊ตฌ๊ธ ์ฌ์ฉ์ ์ด๋ฉ์ผ: {user_info['email']}"
@app.route('/login/kakao')
def login_kakao():
kakao_auth_url = (
f"https://kauth.kakao.com/oauth/authorize?response_type=code"
f"&client_id={KAKAO_CLIENT_ID}&redirect_uri={KAKAO_REDIRECT_URI}"
)
return redirect(kakao_auth_url)
@app.route('/kakao/callback')
def kakao_callback():
code = request.args.get('code')
token_response = requests.post('https://kauth.kakao.com/oauth/token', data={
'grant_type': 'authorization_code',
'client_id': KAKAO_CLIENT_ID,
'redirect_uri': KAKAO_REDIRECT_URI,
'code': code
}).json()
access_token = token_response['access_token']
user_info = requests.get('https://kapi.kakao.com/v2/user/me', headers={
'Authorization': f'Bearer {access_token}'
}).json()
return f"์นด์นด์ค ์ฌ์ฉ์ ID: {user_info['id']}"
if __name__ == '__main__':
app.run(debug=True)
6. ๋ค์ํ ์์ ๋ก๊ทธ์ธ ์ ๊ณต์์ ์ฐ๋ํ๊ธฐ
์์ ๋ก๊ทธ์ธ์ ์ ๊ณตํ๋ ์ฃผ์ ์ ๊ณต์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ๊ฐ ํ๋ซํผ์ OAuth 2.0 ํ์ค ์ ๋ฐ๋ฅด์ง๋ง, ๊ตฌ์ฑ๊ณผ ์ฌ์ฉ ๋ฐฉ๋ฒ ์ ์ฝ๊ฐ์ ์ฐจ์ด๊ฐ ์์ต๋๋ค.
1. ๊ตฌ๊ธ OAuth 2.0
- ์ฌ์ฉ์ ์ ๋ณด : ์ด๋ฉ์ผ, ํ๋กํ ์ฌ์ง, ์ด๋ฆ ๋ฑ
- ์ฌ์ฉ ์์ : Google Drive ๋๋ Gmail API์ ํตํฉ
2. ํ์ด์ค๋ถ OAuth 2.0
- ์ฌ์ฉ์ ์ ๋ณด : ํ๋กํ ์ ๋ณด, ์น๊ตฌ ๋ชฉ๋ก, ํ์ด์ง ์ ๋ณด ๋ฑ
- ์ฌ์ฉ ์์ : ํ์ด์ค๋ถ ํ์ด์ง ๊ด๋ฆฌ ๋๋ ๋ง์ผํ ๋๊ตฌ ์ฐ๋
ํ์ด์ค๋ถ ๊ฐ๋ฐ์ ๋ฌธ์๐
3. ์นด์นด์ค OAuth 2.0
- ์ฌ์ฉ์ ์ ๋ณด : ์นด์นด์คํก ํ๋กํ, ์ด๋ฉ์ผ, ์น๊ตฌ ๋ชฉ๋ก ๋ฑ
- ์ฌ์ฉ ์์ : ์นด์นด์คํก ๋ก๊ทธ์ธ๊ณผ ๋ฉ์์ง API ํ์ฉ
์นด์นด์ค ๊ฐ๋ฐ์ ๋ฌธ์๐
7. ๋ค์ค ์ ๊ณต์ ๋ก๊ทธ์ธ ๊ตฌํ ์์
์๋๋ Flask ๋ฅผ ์ฌ์ฉํด ๊ตฌ๊ธ๊ณผ ์นด์นด์ค์ OAuth ๋ก๊ทธ์ธ ๋ฒํผ ์ ๋์์ ์ ๊ณตํ๋ ์์ ์ ๋๋ค.
์์ ์ฝ๋: Flask์ ๋ค์ค ์์ ๋ก๊ทธ์ธ
from flask import Flask, redirect, request, session, url_for
import requests
app = Flask(__name__)
app.secret_key = 'your_secret_key'
# ๊ตฌ๊ธ OAuth ์ค์
GOOGLE_CLIENT_ID = 'your_google_client_id'
GOOGLE_CLIENT_SECRET = 'your_google_client_secret'
GOOGLE_REDIRECT_URI = 'http://localhost:5000/google/callback'
# ์นด์นด์ค OAuth ์ค์
KAKAO_CLIENT_ID = 'your_kakao_client_id'
KAKAO_REDIRECT_URI = 'http://localhost:5000/kakao/callback'
@app.route('/')
def home():
return '''
<a href="/login/google">๊ตฌ๊ธ ๋ก๊ทธ์ธ</a><br>
<a href="/login/kakao">์นด์นด์ค ๋ก๊ทธ์ธ</a>
'''
@app.route('/login/google')
def login_google():
google_auth_url = (
f"https://accounts.google.com/o/oauth2/auth?response_type=code"
f"&client_id={GOOGLE_CLIENT_ID}&redirect_uri={GOOGLE_REDIRECT_URI}&scope=email"
)
return redirect(google_auth_url)
@app.route('/google/callback')
def google_callback():
code = request.args.get('code')
token_response = requests.post('https://oauth2.googleapis.com/token', data={
'code': code,
'client_id': GOOGLE_CLIENT_ID,
'client_secret': GOOGLE_CLIENT_SECRET,
'redirect_uri': GOOGLE_REDIRECT_URI,
'grant_type': 'authorization_code'
}).json()
access_token = token_response['access_token']
user_info = requests.get('https://www.googleapis.com/oauth2/v1/userinfo', headers={
'Authorization': f'Bearer {access_token}'
}).json()
return f"๊ตฌ๊ธ ์ฌ์ฉ์ ์ด๋ฉ์ผ: {user_info['email']}"
@app.route('/login/kakao')
def login_kakao():
kakao_auth_url = (
f"https://kauth.kakao.com/oauth/authorize?response_type=code"
f"&client_id={KAKAO_CLIENT_ID}&redirect_uri={KAKAO_REDIRECT_URI}"
)
return redirect(kakao_auth_url)
@app.route('/kakao/callback')
def kakao_callback():
code = request.args.get('code')
token_response = requests.post('https://kauth.kakao.com/oauth/token', data={
'grant_type': 'authorization_code',
'client_id': KAKAO_CLIENT_ID,
'redirect_uri': KAKAO_REDIRECT_URI,
'code': code
}).json()
access_token = token_response['access_token']
user_info = requests.get('https://kapi.kakao.com/v2/user/me', headers={
'Authorization': f'Bearer {access_token}'
}).json()
return f"์นด์นด์ค ์ฌ์ฉ์ ID: {user_info['id']}"
if __name__ == '__main__':
app.run(debug=True)
์ฝ๋ ์ค๋ช
- ์ฌ์ฉ์๋ ๊ตฌ๊ธ ๋๋ ์นด์นด์ค ๋ก๊ทธ์ธ ๋ฒํผ ์ ํด๋ฆญํฉ๋๋ค.
- ๋ก๊ทธ์ธ ํ Access Token ์ ๋ฐ๊ธ๋ฐ์ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ์กฐํํฉ๋๋ค.
- ๋ค์ค ์ ๊ณต์ ๋ก๊ทธ์ธ์ ์ง์ํ๋ฉฐ, ์ถ๊ฐ ์ ๊ณต์ ๋ ์์ฝ๊ฒ ํตํฉํ ์ ์์ต๋๋ค.
8. ์์ ๋ก๊ทธ์ธ ๊ตฌํ ์์ ๋ฌธ์ ์ ํด๊ฒฐ ๋ฐฉ๋ฒ
๋ฌธ์ 1: Redirect URI ๋ถ์ผ์น ์ค๋ฅ
- ๋ฌธ์ : ์ ๊ณต์ ์ฝ์์ ๋ฑ๋ก๋ Redirect URI์ ์ค์ ์์ฒญ URI๊ฐ ๋ค๋ฅด๋ฉด ์ธ์ฆ์ ์คํจํฉ๋๋ค.
- ํด๊ฒฐ: ๋ชจ๋ Redirect URI๊ฐ ์ ํํ ์ผ์น ํ๋๋ก ๊ตฌ์ฑํฉ๋๋ค.
๋ฌธ์ 2: ๊ถํ ์์ฒญ ์คํจ
- ๋ฌธ์ : ํ์ ๊ถํ์ ์์ฒญํ์ง ๋ชปํ๋ฉด API ํธ์ถ์ ์คํจํฉ๋๋ค.
- ํด๊ฒฐ: ํ์ํ ์ค์ฝํ๋ฅผ ์ ํํ ๋ช ์ ํ๊ณ ์ฌ์ฉ์์๊ฒ ๋ช ํํ๊ฒ ํ์ํฉ๋๋ค.
๋ฌธ์ 3: ๋ง๋ฃ๋ Access Token
- ๋ฌธ์ : Access Token์ด ๋ง๋ฃ๋๋ฉด API ํธ์ถ์ ์คํจํฉ๋๋ค.
- ํด๊ฒฐ: Refresh Token ์ ์ฌ์ฉํด ์๋์ผ๋ก ์๋ก์ด Access Token์ ๋ฐ๊ธํฉ๋๋ค.
๊ฒฐ๋ก : OAuth 2.0์ ํ์ฉํ ์์ ๋ก๊ทธ์ธ ๊ตฌ์ถ์ ํต์ฌ
OAuth 2.0์ ํ์ฉํ ์์ ๋ก๊ทธ์ธ์ ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํ๊ณ ๊ณ์ ๊ด๋ฆฌ ๋ถ๋ด์ ์ค์ด๋ ๋ฐ ํฐ ๋์์ด ๋ฉ๋๋ค. ๋ค์ํ ์ ๊ณต์์ ์ฐ๋ํ์ฌ ๊ตฌ๊ธ, ํ์ด์ค๋ถ, ์นด์นด์ค ์ ๊ฐ์ ํ๋ซํผ์ ๊ธฐ๋ฅ์ ํ์ฉํ ์ ์์ต๋๋ค. ๋ํ, Redirect URI์ ์ค์ฝํ ์ค์ ์ ์ ํํ ํ๊ณ ๋ณด์ ๊ฐํ๋ฅผ ์ํ PKCE ์ฌ์ฉ ์ ๊ณ ๋ คํด์ผ ํฉ๋๋ค.
FAQ
Q1. ์์
๋ก๊ทธ์ธ ์ ๋ณด์์ ๊ฐํํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ๋์?
A1. PKCE ์ฌ์ฉ ๊ณผ HTTPS ์ ์ก ์ผ๋ก ๋ณด์์ ๊ฐํํ ์ ์์ต๋๋ค.
Q2. ์ฌ์ฉ์๊ฐ ์ฌ๋ฌ ๋ฒ ๋ก๊ทธ์ธํด์ผ ํ๋ ๋ถํธํจ์ ํด๊ฒฐํ ๋ฐฉ๋ฒ์ด ์๋์?
A2. Refresh Token ์ ์ฌ์ฉํด Access Token์ ์๋์ผ๋ก ๊ฐฑ์ ํด ๋ก๊ทธ์ธ ๊ฒฝํ์ ๊ฐ์ ํ ์ ์์ต๋๋ค.
Q3. ์์
๋ก๊ทธ์ธ์ ํ์ํ ์ค์ฝํ๋ ์ด๋ป๊ฒ ์ค์ ํ๋์?
A3. ๊ฐ ์ ๊ณต์์ ๊ฐ๋ฐ์ ์ฝ์์์ ํ์ํ ๊ถํ(์ค์ฝํ) ์ ์ค์ ํด์ผ ํฉ๋๋ค.
Q4. ๋ค์ค ์ ๊ณต์ ๋ก๊ทธ์ธ์ ๋์์ ์ง์ํ๋ ค๋ฉด ์ด๋ป๊ฒ ํ๋์?
A4. ๊ฐ ์ ๊ณต์์ OAuth ์ค์ ์ ๋ฐ๋ก ๊ตฌ์ฑํด ๊ตฌ๊ธ, ์นด์นด์ค, ํ์ด์ค๋ถ ๋ก๊ทธ์ธ์ ๋ชจ๋ ์ง์ํ ์ ์์ต๋๋ค.
Q5. ์์
๋ก๊ทธ์ธ ์ ๊ฐ์ธ์ ๋ณด ๋ณดํธ๋ ์ด๋ป๊ฒ ํด์ผ ํ๋์?
A5. ์ต์ํ์ ์ฌ์ฉ์ ์ ๋ณด ๋ง ์์ฒญํ๊ณ , ๊ฐ์ธ์ ๋ณด ๋ณดํธ ์ ์ฑ
์ ๋ช
ํํ ๊ณ ์งํด์ผ ํฉ๋๋ค.
๋๊ธ