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

Back-end

Slack์œผ๋กœ OAuth ์‚ฌ์šฉํ•˜๊ธฐ

๋ฐ˜์‘ํ˜•

OAuth๋ž€?

OAuth๋Š” ์ž์› ์†Œ์œ ์ž(๊ตฌ๊ธ€, ์นด์นด์˜ค, ํŽ˜์ด์Šค๋ถ, ์Šฌ๋ž™)์™€ HTTP ์„œ๋น„์Šค ๊ฐ„์˜ ์Šน์ธ ์ƒํ˜ธ ์ž‘์šฉ์„ ์กฐ์ •ํ•˜๊ฑฐ๋‚˜ ์ œ 3์ž ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์Šค์Šค๋กœ ์•ก์„ธ์Šค๋ฅผ ์–ป์Œ์œผ๋กœ์จ ์ž์› ์†Œ์œ ์ž์˜ ์„œ๋น„์Šค์— ๋Œ€ํ•œ ์ œํ•œ๋œ ์•ก์„ธ์Šค๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ์ธ์ฆ ํ”„๋ ˆ์ž„์›Œํฌ์ด๋‹ค.

ํ”ํžˆ ๋ณผ ์ˆ˜ ์žˆ๋Š” ๊ตฌ๊ธ€ ๋กœ๊ทธ์ธ, ์นด์นด์˜ค ๋กœ๊ทธ์ธ์€ OAuth๋ฅผ ํ†ตํ•ด์„œ ํ•ด๋‹น ์„œ๋น„์Šค์— ๊ฐ€์ž…ํ•œ ์‚ฌ์šฉ์ž์˜ ์ •๋ณด๋ฅผ ์ผ๋ จ์˜ ๊ณผ์ •์„ ํ†ตํ•ด์„œ ์ œ 3์ž ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์„œ ํšŒ์›๊ฐ€์ž…์„ ์ƒ๋žตํ•˜๊ณ  ์„œ๋น„์Šค๋ฅผ ์ด์šฉํ•  ์ˆ˜ ๋„ ์žˆ๋‹ค.

๋˜ํ•œ OAuth์™€ ์Šฌ๋ž™์—์„œ ์ œ๊ณตํ•˜๋Š” api๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์Šฌ๋ž™์ด ์•„๋‹Œ ๋‚ด๊ฐ€ ๋งŒ๋“  ์›น์—์„œ ์Šฌ๋ž™์— ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๋‚ด๋Š” ๋“ฑ ์ž์› ์†Œ์œ ์ž๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์„œ๋น„์Šค๋ฅผ ์ œ 3์ž ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

OAuth๋Š” ํฌ๊ฒŒ Access Token๊ณผ Scope๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

Slack API์—์„œ OAuth๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹๊ณผ OAuth๋ฅผ ํ†ตํ•ด์„œ ์–ป์€ Access Token์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

Slack์—์„œ OAuth๋กœ Access Token ๋ฐ›๊ธฐ

์ž์› ์†Œ์œ ์ž์˜ ์ž์›(์„œ๋น„์Šค)๋ฅผ ์ด์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Access Token์ด ํ•„์š”ํ•œ๋ฐ, ์Šฌ๋ž™์—์„œ OAuth๋ฅผ ์‚ฌ์šฉํ•ด์„œ api๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  1. scope์— ๋Œ€ํ•œ ์š”์ฒญ์„ ํ•˜๋ฉด code๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  2. ๋ฐ›์€ code๋ฅผ ํ†ตํ•ด์„œ access token์„ ๊ตํ™˜ ๋ฐ›๋Š”๋‹ค.
  3. ๋ฐ›์€ access token์„ ์ด์šฉํ•ด slack api๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

oauth/v2/authorize

๋จผ์ € ์–ด๋–ค ์‚ฌ์šฉ์ž๊ฐ€ ์–ด๋–ค ์„œ๋น„์Šค๋ฅผ ์ด์šฉํ• ์ง€์— ๋Œ€ํ•ด์„œ ์ •ํ•˜๊ณ  ์ด์—๋Œ€ํ•œ code๋ฅผ ๋ฐ›๋Š” api ์ด๋‹ค. ์ด ๊ณผ์ •์—์„œ ์‚ฌ์šฉ์ž๋Š” ํ•ด๋‹น ์„œ๋น„์Šค์˜ ๋กœ๊ทธ์ธ์„ ํ•˜๊ฒŒ๋˜๊ณ , ์‚ฌ์šฉํ•˜๊ฒŒ ๋  ๊ถŒํ•œ์— ๋Œ€ํ•ด์„œ ์•ˆ๋‚ด๋ฅผ ๋ฐ›๊ณ  ๋™์˜๋ฅผ ํ•˜๊ฒŒ ๋œ๋‹ค.(Authorization Request)

์ž์› ์†Œ์œ ์ž๋Š” ํ•ด๋‹น ์š”์ฒญ(Authrization Request)์„ ๋ฐ›์•„์„œ ํ™•์ธ์„ ํ•˜๊ณ  ์œ ํšจํ•œ ์š”์ฒญ์ด๋ผ๋ฉด ์ด๋ฅผ ์Šน์ธํ•˜๊ณ  ์ผ๋ จ์˜ ์ฝ”๋“œ๋ฅผ ๋ณด๋‚ด๊ฒŒ ๋œ๋‹ค.(Authorization Grant)

https://slack.com/oauth/v2/authorize?scope=incoming-webhook,commands&client_id=3336676.569200954261&redirect_uri=example.com

scope - ์‚ฌ์šฉํ•  api๊ฐ€ ์š”๊ตฌํ•˜๋Š” scope๋“ค(๊ถŒํ•œ)

client_id - ์‚ฌ์šฉํ•˜๋ ค๋Š” ์›Œํฌ์ŠคํŽ˜์ด์Šค์— ์•ฑ์„ ๋งŒ๋“ค๋ฉด ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

redirect_uri - ํ•ด๋‹น ์š”์ฒญ์ด ์™„๋ฃŒ๋˜๋ฉด redirect๋  ์ฃผ์†Œ

์‚ฌ์šฉ์ž๊ฐ€ ์œ„ ๋งํฌ๋ฅผ ํด๋ฆญํ•˜๋ฉด ์Šฌ๋ž™ ๋กœ๊ทธ์ธ ํ™”๋ฉด์œผ๋กœ ์ด๋™ํ•˜๊ฒŒ ๋˜๊ณ , ๋กœ๊ทธ์ธ์„ ํ•˜๊ฒŒ๋˜๋ฉด, ํ•ด๋‹น scope์— ๋Œ€ํ•œ ์•ˆ๋‚ด๋ฅผ ๋ฐ›๊ณ  ํ—ˆ์šฉํ•˜๋Š” ํ™”๋ฉด์ด ๋‚˜์˜ค๊ฒŒ ๋œ๋‹ค.

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

oauth.v2.access

oauth/v2/authorize๊ณผ์ •์ด ์™„๋ฃŒ๋˜๋ฉด ์ฝ”๋“œ์™€ ํ•จ๊ป˜ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ๋˜๋Š”๋ฐ, ์ด๋–„ ํ•ด๋‹น ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ํ† ํฐ์„ ๊ตํ™˜ํ•˜๋Š” ๋กœ์ง์„ ์ถ”๊ฐ€ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด๋œ๋‹ค.

curl -F code=1234 -F client_id=3336676.569200954261 -F client_secret=ABCDEFGH https://slack.com/api/oauth.v2.access

code - oauth/v2/authorize์—์„œ ๋ฐ›์€ ์ž„์‹œ ๊ถŒํ•œ ์ฝ”๋“œ

client_id, client_secret - ์•ฑ์„ ๋งŒ๋“ค๋ฉด ์–ป์„ ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ(๊ถŒํ•œ์„ ์š”์ฒญํ•œ ์›Œํฌ์ŠคํŽ˜์ด์Šค ์•ฑ)

์œ„ ์š”์ฒญ์„ ๋ณด๋‚ด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ response๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ณ , ๋‚ด๊ฐ€ ์š”์ฒญํ•œ ๊ถŒํ•œ๊ณผ ๊ทธ์— ๋งž๋Š” access_token์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ณ  ์ด๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์Šฌ๋ž™ api๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

{
    "ok": true,
    "access_token": "xoxb-17653672481-19874698323-pdFZKVeTuE8sk7oOcBrzbqgy",
    "token_type": "bot",
    "scope": "commands,incoming-webhook",
    "bot_user_id": "U0KRQLJ9H",
    "app_id": "A0KRD7HC3",
    "team": {
        "name": "Slack Softball Team",
        "id": "T9TK3CUKW"
    },
    "enterprise": {
        "name": "slack-sports",
        "id": "E12345678"
    },
    "authed_user": {
        "id": "U1234",
        "scope": "chat:write",
        "access_token": "xoxp-1234",
        "token_type": "user"
    }
}

๋งˆ๋ฌด๋ฆฌ

์‚ฌ์‹ค ํšŒ์‚ฌ์—์„œ ์‚ฌ๋‚ด ์‹œ์Šคํ…œ์—์„œ ์Šฌ๋ž™ ๋ฉ”์„ธ์ง€๋ฅผ ๋ฐœ์†กํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ฒŒ ๋˜์„œ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ๋ณด๋ฉด์„œ ์ •๋ฆฌํ•œ ๋ฌธ์„œ์ด๋‹ค ๋ณด๋‹ˆ ๋‚ด๊ฐ€ ์ดํ•ดํ•˜๊ณ  ์‚ฌ์šฉํ•œ? ๋ถ€๋ถ„๋งŒ ์ ์€ ๊ฒƒ ๊ฐ™๋‹ค… ๊ณต์‹ ๋ฌธ์„œ๊ฐ€ ๋„ˆ๋ฌด ์ž์„ธํžˆ ์ž˜ ์ •๋ฆฌ๋˜์–ด ์žˆ์–ด์„œ ๋ถ€์กฑํ•œ ๋ถ€๋ถ„์€ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ๋ณด๊ณ  ๊ตฌํ˜„ํ•˜๋ฉด ๋  ๊ฒƒ ๊ฐ™๋‹ค.

์ด๋ฒˆ์— ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๋ฉด์„œ slack api ๊ณต์‹๋ฌธ์„œ์™€ oauth2 ๊ณต์‹๋ฌธ์„œ๋ฅผ ์—„์ฒญ ๋งŽ์ด ๋ดค๋‹ค. ์™œ ์‚ฌ๋žŒ๋“ค์ด ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ๋ณด๊ณ  ๊ฐœ๋ฐœํ•˜๋Š”์ง€ ์•Œ๊ฒŒ๋˜์—ˆ๋‹ค. ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๋˜‘๊ฐ™์ด ๊ตฌํ˜„ํ•œ ๋ธ”๋กœ๊ทธ๋Š” ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค…๋กœ๊ทธ์ธ๋ฐ–์— ์—†๋‹ค…

์ฐธ๊ณ  ์ž๋ฃŒ

slack oauth2 - https://api.slack.com/authentication/oauth-v2

slack sign in with slack - https://api.slack.com/authentication/sign-in-with-slack

OAuth - https://oauth.net/2/

๋ฐ˜์‘ํ˜•