Skip to content

solapi/sso-node-exmaples

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

21 Commits
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

SSO ํŠœํ† ๋ฆฌ์–ผ

SSO๋ž€?

์‹ฑ๊ธ€์‚ฌ์ธ์˜จ(Single Sign-On, SSO)์€ ํ•˜๋‚˜์˜ ๋กœ๊ทธ์ธ ์ธ์ฆ ์ˆ˜๋‹จ์„๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ
์‚ฌ์ดํŠธ์—์„œ ์ œ๊ณตํ•˜๋Š” ์—ฌ๋Ÿฌ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ˜น์€ API์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์ค‘์•™ํ™”๋œ ์„ธ์…˜ ๋ฐ ์‚ฌ์šฉ์ž ์ธ์ฆ ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค.

์†”๋ผํ”ผ์—์„œ SSO๋ž€?

์†”๋ผํ”ผ์˜ ๋งˆ์ด์‚ฌ์ดํŠธ ์ƒ์„ฑ ๊ธฐ๋Šฅ์„ ์ด์šฉํ•˜์—ฌ ์•ฑ ์•„์ด๋””๋ฅผ ๋ฐœ๊ธ‰ ๋ฐ›๊ณ ,
์•ฑ ์•„์ด๋””๋ฅผ ์ด์šฉํ•˜์—ฌ SSO ํ† ํฐ์„ ๋ฐœ๊ธ‰๋ฐ›์•„ API๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ์„ ๋งํ•ฉ๋‹ˆ๋‹ค.

์•„๋ž˜๋Š” SSO ํ† ํฐ์„ ์ด์šฉํ•˜์—ฌ ์†”๋ผํ”ผ API๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ๋ฒ• ๊ทธ๋ฆฌ๊ณ  ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ๊นŒ์ง€ ์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

SSO ํ† ํฐ์œผ๋กœ ์†”๋ผํ”ผ API ํ˜ธ์ถœ ๋ฐฉ๋ฒ•

์˜ˆ์ œ์ฝ”๋“œ๋Š” ์†”๋ผํ”ผ SSO Examples ์ฝ”๋“œ๋ฅผ ์ฐธ์กฐํ•˜์˜€์Šต๋‹ˆ๋‹ค.

1. ๋งˆ์ด์‚ฌ์ดํŠธ ๋งŒ๋“ค๊ธฐ & ์•ฑ ์•„์ด๋”” ๋ฐœ๊ธ‰

SSO๋ฅผ ์ด์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์†”๋ผํ”ผ์˜ ๋งˆ์ด์‚ฌ์ดํŠธ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
๋งˆ์ด์‚ฌ์ดํŠธ์˜ ์•ฑ ์•„์ด๋””๋ฅผ ์ด์šฉํ•˜์—ฌ SSO ํ† ํฐ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
'๋งˆ์ด์‚ฌ์ดํŠธ ์ƒ์„ฑ' ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜์—ฌ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

image

๋งˆ์ด์‚ฌ์ดํŠธ ์ด๋ฆ„ ๊ทธ๋ฆฌ๊ณ  ๋ฐœ์‹  ์ด๋ฉ”์ผ์„ ์ž‘์„ฑํ•˜์‹  ํ›„ ๋Œ€ํ‘œ์ฃผ์†Œ๋ฅผ ์„ค์ •ํ•œ ๋’ค ์•„๋ž˜์ชฝ์˜ '๋งˆ์ด์‚ฌ์ดํŠธ ์ƒ์„ฑ' ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ์ƒ์„ฑ์ด ์™„๋ฃŒ๋ฉ๋‹ˆ๋‹ค.
๋กœ๊ณ ๋‚˜ ์ปฌ๋Ÿฌ๋ฅผ ์›ํ•˜์‹œ๋Š” ๋Œ€๋กœ ๋ณ€๊ฒฝํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

image

์ƒ์„ฑ๋œ ๋งˆ์ด์‚ฌ์ดํŠธ ์˜ค๋ฅธ์ชฝ์— ์žˆ๋Š” '๋งˆ์ด์‚ฌ์ดํŠธ ๊ด€๋ฆฌ'๋ฅผ ํด๋ฆญํ•˜๋ฉด ๊ด€๋ฆฌ ํŽ˜์ด์ง€๋กœ ๊ฐˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด๊ณณ์—์„œ ๋งˆ์ด์‚ฌ์ดํŠธ์— ๊ฐ€์ž…ํ•œ ํšŒ์›๋“ค์„ ๋ณด๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

image

'๋งˆ์ด์‚ฌ์ดํŠธ ๊ด€๋ฆฌ' ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜์—ฌ ๋“ค์–ด๊ฐ€๋ฉด ๋ณด์ด๋Š” ์œ„์ชฝ ์ฃผ์†Œ์ฐฝ์— 'mysite/' ๋’ท ๋ถ€๋ถ„์— ์ ํ˜€์žˆ๋Š” ๊ฒƒ์ด ์•ฑ ์•„์ด๋”” ์ž…๋‹ˆ๋‹ค.

image

2. ๊ด€๋ฆฌ์ž์—๊ฒŒ IP ํ—ˆ์šฉ ์š”์ฒญ

ํ™”๋ฉด ์˜ค๋ฅธ์ชฝ ์•„๋ž˜ ์ƒ๋‹ด์ฐฝ์— ๋งˆ์ด์‚ฌ์ดํŠธ์˜ ์•ฑ์•„์ด๋””์™€ ํ•จ๊ป˜ ๊ด€๋ฆฌ์ž์—๊ฒŒ IP ํ—ˆ์šฉ์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.
ํ—ˆ์šฉ์ด๋œ IP์—์„œ๋งŒ SSO ํ† ํฐ์„ ์ด์šฉํ•œ API ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

image

3. ์ƒ์„ฑ๋œ ์•ฑ ์•„์ด๋””๋กœ SSO ํ† ํฐ ๋ฐœ๊ธ‰

๋ฐ›์€ ์•ฑ ์•„์ด๋””๋กœ SSO ํ† ํฐ ๋ฐœ๊ธ‰์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.

[Requset]
const moment = require('moment-timezone')
const { HmacSHA256 } = require('crypto-js')
const apiKey = '##API_KEY##'
const apiSecret = '##API_SECRET##'

// API KEY, API SECRET ์œผ๋กœ ์ธ์ฆ๊ฐ’ ๋งŒ๋“ค์–ด ํ—ค๋”์— ์„ค์ •
const getApiKeyAuthHeader = () => {
  const date = moment().tz('Asia/Seoul').format('YYYY-MM-DD HH:mm:ss')
  const salt = (Math.random() + 1).toString(36).substring(7) // ๋žœ๋คํ•œ ๋ฌธ์ž์—ด
  const hmacData = date + salt
  const signature = HmacSHA256(hmacData, apiSecret).toString()
  return { Authorization: `HMAC-SHA256 apiKey=${apiKey}, date=${date}, salt=${salt}, signature=${signature}` }
}

/** Step 1. ์•ฑ ์•„์ด๋””์™€ ๊ฐ€์ž…ํ•  ํšŒ์›์ •๋ณด๋ฅผ ์ด์šฉํ•˜์—ฌ SSO Token ๋ฐœ๊ธ‰ */
const getSSOToken = async () => {
  const form = {
    appId: '##APP_ID##', // ๋ฐœ๊ธ‰๋ฐ›์€ ์•ฑ ์•„์ด๋””
    email: '##EMAIL##', // ํšŒ์›๊ฐ€์ž…์— ์‚ฌ์šฉ๋  ์ด๋ฉ”์ผ ์ฃผ์†Œ
    password: '##PASSWORD##', // ํšŒ์›๊ฐ€์ž…์— ์‚ฌ์šฉ๋  ์•”ํ˜ธ
    customerKey: '##MEMBER_CUSTOMER_KEY##' // ๋งˆ์ด์‚ฌ์ดํŠธ์—์„œ ์‚ฌ์šฉํ•  ํšŒ์› ๊ตฌ๋ถ„ ํ‚ค
  }
  const result = await request({
    method: 'POST',
    uri: `https://api.solapi.com/appstore/v2/sso/connect`,
    form,
    json: true,
    // OAuth2 or API Key๋กœ ๋œ ์ธ์ฆ ์ˆ˜๋‹จ ๊ฐ’, ์ž์„ธํ•œ ๋‚ด์šฉ์€ https://developers.solapi.dev/references/authentication์„ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”
    headers: getApiKeyAuthHeader()
  })
  console.log(result)
}
getSSOToken()
[Response]
{
  ssoToken: 'eyJhbGciOiJIUzI1NiIsInR53216IkpXVCJ9.eyJhcHBJZCI6Ik123U5zQUUzYUp5QiIsIm1lbWJlcklkIjoiTUVNemNhZHo0WmVoUGkiLCJhY2NvdW50SWQiOiIyMjExMDgxODA5NzEwMiIsImlhdCI6MTY2Nzg4MzY5N30.rKGE_xa1ONf5vXn14wI23nlNLeNVst0gEJ_b9E9rReI'
}

4. ๋ฐœ๊ธ‰๋ฐ›์€ SSO ํ† ํฐ์œผ๋กœ API ์š”์ฒญ

๋ฐœ๊ธ‰๋ฐ›์€ SSO ํ† ํฐ์œผ๋กœ ์†”๋ผํ”ผ API ์ด์šฉ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

[Request]
const request = require('request-promise')

const getMemberInfo = async () => {
  const result = await request({
    method: 'GET',
    uri: `https://api.solapi.com/users/v1/member`,
    json: true,
    // SSO ํ† ํฐ ๊ฐ’ ์„ค์ •
    headers: { Authorization: `sso ##SSO TOKEN ##` }
  })
  console.log(result)
}
getMemberInfo()
[Response]
{
  name: 'user',
  phoneNumber: null,
  extraPhoneNumbers: [],
  status: 'ACTIVE',
  selectedAccountId: '22110348097102',
  betaMicroservices: null,
  appId: 'NGeNsAE334yB',
  activeDeviceAuth: false,
  isTrial: false,
  memberId: 'MEMzc34z4ZehPi',
  email: 'user@nurigo.net',
  devices: [],
  loginSessions: [],
  dateCreated: '2022-11-08T05:01:37.097Z',
  dateUpdated: '2022-11-08T05:01:37.166Z'
}

SSO ํ† ํฐ์œผ๋กœ ๋งˆ์ด์‚ฌ์ดํŠธ ๋กœ๊ทธ์ธ & ํŽ˜์ด์ง€ ์ด๋™ ๋ฐฉ๋ฒ•

SSO ํ† ํฐ์„ ์ฟผ๋ฆฌ๊ฐ’์œผ๋กœ ์•„๋ž˜ ์ฃผ์†Œ๋กœ ๋ณด๋‚ด๋ฉด ๋กœ๊ทธ์ธ์ด ์™„๋ฃŒ๋œ์ฑ„๋กœ ๋ณด๋‚ด์ฃผ์‹  ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ์ฃผ์†Œ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.
์ฒ˜์Œ์—๋Š” ์ ‘์†์‹œ ์•„๋ž˜ ์ด๋ฏธ์ง€ ์ฒ˜๋Ÿผ ๋ณธ์ธ์ธ์ฆ์„ ํ•ด์ฃผ์…”์•ผํ•ฉ๋‹ˆ๋‹ค.

image

[๋ฉ”์ธํŽ˜์ด์ง€๋กœ ์ด๋™]
https://api.solapi.com/appstore/v2/sso/connect-homepage?redirecturi=#{๋งˆ์ด์‚ฌ์ดํŠธ์ฃผ์†Œ}/dashboard

image

[๋ฐœ์‹ ๋ฒˆํ˜ธ๋กœ ์ด๋™]
https://api.solapi.com/appstore/v2/sso/connect-homepage?redirecturi=#{๋งˆ์ด์‚ฌ์ดํŠธ์ฃผ์†Œ}/senderids

image

[์ถฉ์ „ํŽ˜์ด์ง€๋กœ ์ด๋™]
https://api.solapi.com/appstore/v2/sso/connect-homepage?redirecturi=#{๋งˆ์ด์‚ฌ์ดํŠธ์ฃผ์†Œ}/balance

image


[๊ด€๋ จ๋ฌธ์„œ]

Site | API Refernces Docs |

About

Solapi SSO Examples

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published