๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

OAuth์˜ ๊ฐœ๋…๊ณผ ํ•„์š”์„ฑ: ์•ˆ์ „ํ•œ ์ธ์ฆ๊ณผ ๊ถŒํ•œ ๋ถ€์—ฌ์˜ ํ•ต์‹ฌ ์ดํ•ดํ•˜๊ธฐ

mrmount 2024. 10. 18.

 

 

 

OAuth๋ž€ ๋ฌด์—‡์ธ๊ฐ€?

OAuth(Open Authorization) ๋Š” ์™ธ๋ถ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‚ฌ์šฉ์ž์˜ ์ž๊ฒฉ ์ฆ๋ช…์„ ๊ณต์œ ํ•˜์ง€ ์•Š๊ณ  ์„œ๋น„์Šค์— ์•ˆ์ „ํ•˜๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ์ธ์ฆ ๋ฐ ๊ถŒํ•œ ๋ถ€์—ฌ ํ”„๋กœํ† ์ฝœ ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์‚ฌ์šฉ์ž๊ฐ€ ๊ตฌ๊ธ€ ๊ณ„์ • ์œผ๋กœ ๋‹ค๋ฅธ ์›น์‚ฌ์ดํŠธ์— ๋กœ๊ทธ์ธํ•  ๋•Œ OAuth๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

 


 

1. OAuth๊ฐ€ ํ•ด๊ฒฐํ•˜๋Š” ๋ฌธ์ œ์ 

 

๋ฌธ์ œ 1: ๋น„๋ฐ€๋ฒˆํ˜ธ ๊ณต์œ ์˜ ์œ„ํ—˜

๊ณผ๊ฑฐ์—๋Š” ์—ฌ๋Ÿฌ ์„œ๋น„์Šค์—์„œ ์‚ฌ์šฉ์ž์˜ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ง์ ‘ ๋ฐ›์•„ ์ธ์ฆํ–ˆ์ง€๋งŒ, ์ด๋Š” ๋ณด์•ˆ์ƒ ํฐ ์œ„ํ—˜ ์„ ์ดˆ๋ž˜ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์œ ์ถœ๋˜๋ฉด ๋ชจ๋“  ์„œ๋น„์Šค์— ๋Œ€ํ•œ ์ ‘๊ทผ ๊ถŒํ•œ์ด ๋…ธ์ถœ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฌธ์ œ 2: ๊ถŒํ•œ ์ œํ•œ์˜ ์–ด๋ ค์›€

์„œ๋น„์Šค์— ๋ถ€๋ถ„์  ์ ‘๊ทผ ๊ถŒํ•œ ๋งŒ ๋ถ€์—ฌํ•ด์•ผ ํ•  ๋•Œ, ๊ธฐ์กด ๋ฐฉ์‹์€ ์ „์ฒด ๊ณ„์ •์„ ๊ณต์œ ํ•ด์•ผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ด€๋ฆฌ๊ฐ€ ์–ด๋ ค์› ์Šต๋‹ˆ๋‹ค.

OAuth์˜ ํ•ด๊ฒฐ์ฑ…:

  • ๋น„๋ฐ€๋ฒˆํ˜ธ ์—†์ด ์•ˆ์ „ํ•œ ์ ‘๊ทผ : OAuth๋Š” Access Token(์•ก์„ธ์Šค ํ† ํฐ) ์„ ์‚ฌ์šฉํ•ด ์ž๊ฒฉ ์ฆ๋ช… ์—†์ด๋„ ์ธ์ฆ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ถ€๋ถ„์  ๊ถŒํ•œ ๋ถ€์—ฌ : OAuth๋Š” ์‚ฌ์šฉ์ž ๊ถŒํ•œ์„ ์„ธ๋ถ„ํ™”ํ•ด ํŠน์ • ๋ฐ์ดํ„ฐ๋‚˜ ๊ธฐ๋Šฅ์—๋งŒ ์ ‘๊ทผ์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค.

 


 

2. ์ธ์ฆ(Authentication)๊ณผ ์ธ๊ฐ€(Authorization)์˜ ์ฐจ์ด

๊ตฌ๋ถ„ ์ธ์ฆ (Authentication) ์ธ๊ฐ€ (Authorization)
์˜๋ฏธ ์‚ฌ์šฉ์ž๊ฐ€ ๋ˆ„๊ตฌ์ธ์ง€ ํ™•์ธ ํ•˜๋Š” ๊ณผ์ • ์‚ฌ์šฉ์ž๊ฐ€ ๋ฌด์—‡์„ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๊ฒฐ์ •
์˜ˆ์‹œ ๋กœ๊ทธ์ธ ์‹œ ์•„์ด๋””์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ ํ™•์ธ ๋กœ๊ทธ์ธ ํ›„ ํŠน์ • ๊ธฐ๋Šฅ ์ ‘๊ทผ ๊ถŒํ•œ ๋ถ€์—ฌ
OAuth ์—ญํ•  OAuth๋Š” ์ธ๊ฐ€ ํ”„๋กœ์„ธ์Šค์— ์ง‘์ค‘ํ•ฉ๋‹ˆ๋‹ค ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ฐ์ดํ„ฐ ์ ‘๊ทผ์„ ํ—ˆ๊ฐ€ ํ•ฉ๋‹ˆ๋‹ค



OAuth์—์„œ์˜ ์ธ์ฆ๊ณผ ์ธ๊ฐ€

OAuth ์ž์ฒด๋Š” ์ธ์ฆ(Authentication) ๋ณด๋‹ค ์ธ๊ฐ€(Authorization) ์— ์ค‘์ ์„ ๋‘ก๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์‚ฌ์šฉ์ž๊ฐ€ ์ž์‹ ์˜ ๊ตฌ๊ธ€ ๋“œ๋ผ์ด๋ธŒ ํŒŒ์ผ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ ๋‹ค๋ฅธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋ถ€์—ฌํ•  ๋•Œ OAuth๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

 


 

3. OAuth์˜ ์‚ฌ์šฉ ์‚ฌ๋ก€

OAuth๋Š” ๋‹ค์–‘ํ•œ ์†Œ์…œ ๋กœ๊ทธ์ธ ๊ณผ API ํ˜ธ์ถœ ์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ OAuth์˜ ๋Œ€ํ‘œ์ ์ธ ์‚ฌ์šฉ ์‚ฌ๋ก€์ž…๋‹ˆ๋‹ค.

1. ๊ตฌ๊ธ€ ๋กœ๊ทธ์ธ ์—ฐ๋™

์›น์‚ฌ์ดํŠธ์—์„œ “๊ตฌ๊ธ€ ๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธ” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•  ๋•Œ OAuth๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ๊ตฌ๊ธ€ ๊ณ„์ •์„ ํ†ตํ•ด ๋น ๋ฅด๊ณ  ์•ˆ์ „ํ•˜๊ฒŒ ๋กœ๊ทธ์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2. ํŽ˜์ด์Šค๋ถ๊ณผ์˜ API ์—ฐ๋™

ํƒ€์‚ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ํŽ˜์ด์Šค๋ถ API ๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž์˜ ํ”„๋กœํ•„ ์ •๋ณด๋ฅผ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ๋„ OAuth๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ํ”„๋กœํ•„ ์ •๋ณด์™€ ์‚ฌ์ง„์—๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์ œํ•œ๋œ ๊ถŒํ•œ ์„ ๋ถ€์—ฌํ•ฉ๋‹ˆ๋‹ค.

3. ํ”ผํŠธ๋‹ˆ์Šค ์•ฑ๊ณผ ๊ฑด๊ฐ• ๋ฐ์ดํ„ฐ ์—ฐ๋™

์• ํ”Œ ํ—ฌ์Šค์™€ ๊ฐ™์€ ํ”Œ๋žซํผ์— ์ ‘๊ทผํ•ด ์‚ฌ์šฉ์ž์˜ ๊ฑด๊ฐ• ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ํ”ผํŠธ๋‹ˆ์Šค ์•ฑ ์—์„œ๋„ OAuth๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

 


 

4. OAuth์˜ ์ž‘๋™ ๋ฐฉ์‹

OAuth๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๊ถŒํ•œ ๋ถ€์—ฌ ์ฝ”๋“œ(Authorization Code) ๋ฅผ ์‚ฌ์šฉํ•ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” OAuth์˜ ๊ธฐ๋ณธ ํ๋ฆ„์ž…๋‹ˆ๋‹ค.

  1. ์‚ฌ์šฉ์ž๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋กœ๊ทธ์ธ ํ•˜๊ณ  OAuth ๊ถŒํ•œ ๋ถ€์—ฌ๋ฅผ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.
  2. ๊ถŒํ•œ ๋ถ€์—ฌ ์„œ๋ฒ„ ๊ฐ€ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋กœ๊ทธ์ธ ๋ฐ ๊ถŒํ•œ ๋ถ€์—ฌ ์ฐฝ์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
  3. ์‚ฌ์šฉ์ž๊ฐ€ ๊ถŒํ•œ ๋ถ€์—ฌ๋ฅผ ์Šน์ธ ํ•˜๋ฉด ์ธ์ฆ ์ฝ”๋“œ(Authorization Code) ๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.
  4. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์ธ์ฆ ์ฝ”๋“œ๋ฅผ ์ด์šฉํ•ด Access Token ์„ ๋ฐœ๊ธ‰๋ฐ›๊ณ  API๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

 


 

5. OAuth ๊ตฌํ˜„ ์˜ˆ์ œ (Python ์ฝ”๋“œ)

์•„๋ž˜๋Š” Flask์™€ Requests ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฅผ ์‚ฌ์šฉํ•ด ๊ตฌ๊ธ€ OAuth๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.

from flask import Flask, redirect, request, session, url_for
import requests

app = Flask(__name__)
app.secret_key = 'your_secret_key'

CLIENT_ID = 'your_client_id'
CLIENT_SECRET = 'your_client_secret'
REDIRECT_URI = 'http://localhost:5000/callback'
AUTHORIZATION_URL = 'https://accounts.google.com/o/oauth2/auth'
TOKEN_URL = 'https://accounts.google.com/o/oauth2/token'

@app.route('/')
def home():
    return '<a href="/login">๊ตฌ๊ธ€ ๋กœ๊ทธ์ธ</a>'

@app.route('/login')
def login():
    auth_url = f"{AUTHORIZATION_URL}?response_type=code&client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}&scope=email"
    return redirect(auth_url)

@app.route('/callback')
def callback():
    code = request.args.get('code')
    token_response = requests.post(TOKEN_URL, data={
        'code': code,
        'client_id': CLIENT_ID,
        'client_secret': CLIENT_SECRET,
        'redirect_uri': REDIRECT_URI,
        'grant_type': 'authorization_code'
    }).json()
    session['access_token'] = token_response['access_token']
    return '๋กœ๊ทธ์ธ ์„ฑ๊ณต!'

if __name__ == '__main__':
    app.run(debug=True)

 

 

OAuth๋ž€ ๋ฌด์—‡์ธ๊ฐ€?

OAuth(Open Authorization) ๋Š” ์™ธ๋ถ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‚ฌ์šฉ์ž์˜ ์ž๊ฒฉ ์ฆ๋ช…์„ ๊ณต์œ ํ•˜์ง€ ์•Š๊ณ  ์„œ๋น„์Šค์— ์•ˆ์ „ํ•˜๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ์ธ์ฆ ๋ฐ ๊ถŒํ•œ ๋ถ€์—ฌ ํ”„๋กœํ† ์ฝœ ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์‚ฌ์šฉ์ž๊ฐ€ ๊ตฌ๊ธ€ ๊ณ„์ • ์œผ๋กœ ๋‹ค๋ฅธ ์›น์‚ฌ์ดํŠธ์— ๋กœ๊ทธ์ธํ•  ๋•Œ OAuth๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

 


 

1. OAuth๊ฐ€ ํ•ด๊ฒฐํ•˜๋Š” ๋ฌธ์ œ์ 

 

๋ฌธ์ œ 1: ๋น„๋ฐ€๋ฒˆํ˜ธ ๊ณต์œ ์˜ ์œ„ํ—˜

๊ณผ๊ฑฐ์—๋Š” ์—ฌ๋Ÿฌ ์„œ๋น„์Šค์—์„œ ์‚ฌ์šฉ์ž์˜ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ง์ ‘ ๋ฐ›์•„ ์ธ์ฆํ–ˆ์ง€๋งŒ, ์ด๋Š” ๋ณด์•ˆ์ƒ ํฐ ์œ„ํ—˜ ์„ ์ดˆ๋ž˜ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์œ ์ถœ๋˜๋ฉด ๋ชจ๋“  ์„œ๋น„์Šค์— ๋Œ€ํ•œ ์ ‘๊ทผ ๊ถŒํ•œ์ด ๋…ธ์ถœ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฌธ์ œ 2: ๊ถŒํ•œ ์ œํ•œ์˜ ์–ด๋ ค์›€

์„œ๋น„์Šค์— ๋ถ€๋ถ„์  ์ ‘๊ทผ ๊ถŒํ•œ ๋งŒ ๋ถ€์—ฌํ•ด์•ผ ํ•  ๋•Œ, ๊ธฐ์กด ๋ฐฉ์‹์€ ์ „์ฒด ๊ณ„์ •์„ ๊ณต์œ ํ•ด์•ผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ด€๋ฆฌ๊ฐ€ ์–ด๋ ค์› ์Šต๋‹ˆ๋‹ค.

OAuth์˜ ํ•ด๊ฒฐ์ฑ…:

  • ๋น„๋ฐ€๋ฒˆํ˜ธ ์—†์ด ์•ˆ์ „ํ•œ ์ ‘๊ทผ : OAuth๋Š” Access Token(์•ก์„ธ์Šค ํ† ํฐ) ์„ ์‚ฌ์šฉํ•ด ์ž๊ฒฉ ์ฆ๋ช… ์—†์ด๋„ ์ธ์ฆ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ถ€๋ถ„์  ๊ถŒํ•œ ๋ถ€์—ฌ : OAuth๋Š” ์‚ฌ์šฉ์ž ๊ถŒํ•œ์„ ์„ธ๋ถ„ํ™”ํ•ด ํŠน์ • ๋ฐ์ดํ„ฐ๋‚˜ ๊ธฐ๋Šฅ์—๋งŒ ์ ‘๊ทผ์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค.

 


 

2. ์ธ์ฆ(Authentication)๊ณผ ์ธ๊ฐ€(Authorization)์˜ ์ฐจ์ด

๊ตฌ๋ถ„ ์ธ์ฆ (Authentication) ์ธ๊ฐ€ (Authorization)
์˜๋ฏธ ์‚ฌ์šฉ์ž๊ฐ€ ๋ˆ„๊ตฌ์ธ์ง€ ํ™•์ธ ํ•˜๋Š” ๊ณผ์ • ์‚ฌ์šฉ์ž๊ฐ€ ๋ฌด์—‡์„ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๊ฒฐ์ •
์˜ˆ์‹œ ๋กœ๊ทธ์ธ ์‹œ ์•„์ด๋””์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ ํ™•์ธ ๋กœ๊ทธ์ธ ํ›„ ํŠน์ • ๊ธฐ๋Šฅ ์ ‘๊ทผ ๊ถŒํ•œ ๋ถ€์—ฌ
OAuth ์—ญํ•  OAuth๋Š” ์ธ๊ฐ€ ํ”„๋กœ์„ธ์Šค์— ์ง‘์ค‘ํ•ฉ๋‹ˆ๋‹ค ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ฐ์ดํ„ฐ ์ ‘๊ทผ์„ ํ—ˆ๊ฐ€ ํ•ฉ๋‹ˆ๋‹ค



OAuth์—์„œ์˜ ์ธ์ฆ๊ณผ ์ธ๊ฐ€

OAuth ์ž์ฒด๋Š” ์ธ์ฆ(Authentication) ๋ณด๋‹ค ์ธ๊ฐ€(Authorization) ์— ์ค‘์ ์„ ๋‘ก๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์‚ฌ์šฉ์ž๊ฐ€ ์ž์‹ ์˜ ๊ตฌ๊ธ€ ๋“œ๋ผ์ด๋ธŒ ํŒŒ์ผ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ ๋‹ค๋ฅธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋ถ€์—ฌํ•  ๋•Œ OAuth๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

 


 

3. OAuth์˜ ์‚ฌ์šฉ ์‚ฌ๋ก€

OAuth๋Š” ๋‹ค์–‘ํ•œ ์†Œ์…œ ๋กœ๊ทธ์ธ ๊ณผ API ํ˜ธ์ถœ ์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ OAuth์˜ ๋Œ€ํ‘œ์ ์ธ ์‚ฌ์šฉ ์‚ฌ๋ก€์ž…๋‹ˆ๋‹ค.

1. ๊ตฌ๊ธ€ ๋กœ๊ทธ์ธ ์—ฐ๋™

์›น์‚ฌ์ดํŠธ์—์„œ “๊ตฌ๊ธ€ ๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธ” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•  ๋•Œ OAuth๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ๊ตฌ๊ธ€ ๊ณ„์ •์„ ํ†ตํ•ด ๋น ๋ฅด๊ณ  ์•ˆ์ „ํ•˜๊ฒŒ ๋กœ๊ทธ์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2. ํŽ˜์ด์Šค๋ถ๊ณผ์˜ API ์—ฐ๋™

ํƒ€์‚ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ํŽ˜์ด์Šค๋ถ API ๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž์˜ ํ”„๋กœํ•„ ์ •๋ณด๋ฅผ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ๋„ OAuth๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ํ”„๋กœํ•„ ์ •๋ณด์™€ ์‚ฌ์ง„์—๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์ œํ•œ๋œ ๊ถŒํ•œ ์„ ๋ถ€์—ฌํ•ฉ๋‹ˆ๋‹ค.

3. ํ”ผํŠธ๋‹ˆ์Šค ์•ฑ๊ณผ ๊ฑด๊ฐ• ๋ฐ์ดํ„ฐ ์—ฐ๋™

์• ํ”Œ ํ—ฌ์Šค์™€ ๊ฐ™์€ ํ”Œ๋žซํผ์— ์ ‘๊ทผํ•ด ์‚ฌ์šฉ์ž์˜ ๊ฑด๊ฐ• ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ํ”ผํŠธ๋‹ˆ์Šค ์•ฑ ์—์„œ๋„ OAuth๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

 


 

4. OAuth์˜ ์ž‘๋™ ๋ฐฉ์‹

OAuth๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๊ถŒํ•œ ๋ถ€์—ฌ ์ฝ”๋“œ(Authorization Code) ๋ฅผ ์‚ฌ์šฉํ•ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” OAuth์˜ ๊ธฐ๋ณธ ํ๋ฆ„์ž…๋‹ˆ๋‹ค.

  1. ์‚ฌ์šฉ์ž๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋กœ๊ทธ์ธ ํ•˜๊ณ  OAuth ๊ถŒํ•œ ๋ถ€์—ฌ๋ฅผ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.
  2. ๊ถŒํ•œ ๋ถ€์—ฌ ์„œ๋ฒ„ ๊ฐ€ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋กœ๊ทธ์ธ ๋ฐ ๊ถŒํ•œ ๋ถ€์—ฌ ์ฐฝ์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
  3. ์‚ฌ์šฉ์ž๊ฐ€ ๊ถŒํ•œ ๋ถ€์—ฌ๋ฅผ ์Šน์ธ ํ•˜๋ฉด ์ธ์ฆ ์ฝ”๋“œ(Authorization Code) ๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.
  4. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์ธ์ฆ ์ฝ”๋“œ๋ฅผ ์ด์šฉํ•ด Access Token ์„ ๋ฐœ๊ธ‰๋ฐ›๊ณ  API๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

 


 

5. OAuth ๊ตฌํ˜„ ์˜ˆ์ œ (Python ์ฝ”๋“œ)

์•„๋ž˜๋Š” Flask์™€ Requests ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฅผ ์‚ฌ์šฉํ•ด ๊ตฌ๊ธ€ OAuth๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.

from flask import Flask, redirect, request, session, url_for
import requests

app = Flask(__name__)
app.secret_key = 'your_secret_key'

CLIENT_ID = 'your_client_id'
CLIENT_SECRET = 'your_client_secret'
REDIRECT_URI = 'http://localhost:5000/callback'
AUTHORIZATION_URL = 'https://accounts.google.com/o/oauth2/auth'
TOKEN_URL = 'https://accounts.google.com/o/oauth2/token'

@app.route('/')
def home():
    return '<a href="/login">๊ตฌ๊ธ€ ๋กœ๊ทธ์ธ</a>'

@app.route('/login')
def login():
    auth_url = f"{AUTHORIZATION_URL}?response_type=code&client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}&scope=email"
    return redirect(auth_url)

@app.route('/callback')
def callback():
    code = request.args.get('code')
    token_response = requests.post(TOKEN_URL, data={
        'code': code,
        'client_id': CLIENT_ID,
        'client_secret': CLIENT_SECRET,
        'redirect_uri': REDIRECT_URI,
        'grant_type': 'authorization_code'
    }).json()
    session['access_token'] = token_response['access_token']
    return '๋กœ๊ทธ์ธ ์„ฑ๊ณต!'

if __name__ == '__main__':
    app.run(debug=True)

 

์ฝ”๋“œ ์„ค๋ช…:

  1. ๊ตฌ๊ธ€ ๋กœ๊ทธ์ธ URL๋กœ ๋ฆฌ๋””๋ ‰์…˜ : ์‚ฌ์šฉ์ž๊ฐ€ ๊ถŒํ•œ์„ ์Šน์ธํ•˜๋ฉด ์ฝœ๋ฐฑ URL๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.
  2. Access Token ๋ฐœ๊ธ‰ : ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์ธ์ฆ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•ด Access Token ์„ ๋ฐœ๊ธ‰๋ฐ›์Šต๋‹ˆ๋‹ค.
  3. API ํ˜ธ์ถœ์— Access Token ์‚ฌ์šฉ : ๋กœ๊ทธ์ธ ์„ฑ๊ณต ํ›„, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๊ตฌ๊ธ€ API๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 


 

OAuth์™€ ๊ด€๋ จ๋œ ์ตœ์‹  ํŠธ๋ Œ๋“œ

  • OAuth 2.1 ํ‘œ์ค€์ด ๋“ฑ์žฅํ•˜๋ฉฐ ๋ณด์•ˆ์„ฑ์ด ๊ฐ•ํ™” ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • PKCE(Proof Key for Code Exchange) ๊ฐ€ ํ•„์ˆ˜๋กœ ๊ถŒ์žฅ๋˜๋ฉฐ ํด๋ผ์ด์–ธํŠธ ์ธก ๋ณด์•ˆ ์ด ๊ฐ•ํ™”๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • ๋Œ€๋ถ€๋ถ„์˜ ์†Œ์…œ ๋ฏธ๋””์–ด์™€ ํด๋ผ์šฐ๋“œ ์„œ๋น„์Šค๋Š” OAuth๋ฅผ ์‚ฌ์šฉํ•ด ๋ฐ์ดํ„ฐ ์ ‘๊ทผ์„ ์ œ์–ด ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 


 

FAQ

Q1. OAuth์™€ OpenID Connect๋Š” ๋ฌด์—‡์ด ๋‹ค๋ฅธ๊ฐ€์š”?
A1. OAuth๋Š” ์ธ๊ฐ€(Authorization) ์— ์ค‘์ ์„ ๋‘๊ณ , OpenID Connect๋Š” ์ธ์ฆ(Authentication) ์— ์ค‘์ ์„ ๋‘ก๋‹ˆ๋‹ค.

Q2. OAuth 2.0๊ณผ OAuth 2.1์˜ ์ฐจ์ด๋Š” ๋ฌด์—‡์ธ๊ฐ€์š”?
A2. OAuth 2.1์€ ๋ณด์•ˆ ๊ฐ•ํ™”๋ฅผ ์œ„ํ•ด PKCE ๋ฅผ ํ•„์ˆ˜ํ™”ํ•˜๊ณ , Implicit Grant ๋ฐฉ์‹์„ ์ œ๊ฑฐํ–ˆ์Šต๋‹ˆ๋‹ค.

Q3. OAuth์—์„œ Refresh Token์€ ๋ฌด์—‡์ธ๊ฐ€์š”?
A3. Refresh Token์€ Access Token์ด ๋งŒ๋ฃŒ๋œ ํ›„ ์ƒˆ๋กœ์šด Access Token ์„ ๋ฐœ๊ธ‰๋ฐ›๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

Q4. OAuth ์‚ฌ์šฉ ์‹œ ๋ณด์•ˆ ์œ„ํ—˜์€ ์—†๋‚˜์š”?
A4. OAuth๋Š” ์•ˆ์ „ํ•˜์ง€๋งŒ, Access Token ํƒˆ์ทจ ์™€ ๊ฐ™์€ ๊ณต๊ฒฉ์— ์ฃผ์˜ํ•ด์•ผ ํ•˜๋ฉฐ PKCE ์™€ HTTPS๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Q5. ๋ชจ๋“  API ํ˜ธ์ถœ์— OAuth๊ฐ€ ํ•„์š”ํ•œ๊ฐ€์š”?
A5. ๋ชจ๋“  API๊ฐ€ OAuth๋ฅผ ์š”๊ตฌํ•˜์ง€๋Š” ์•Š์ง€๋งŒ, ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๋Š” API ๋Š” ๋Œ€๋ถ€๋ถ„ OAuth๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 


๋Œ“๊ธ€