Feathers: ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์— ๋Œ€ํ•œ ์ง€์› ์ถ”๊ฐ€

์— ๋งŒ๋“  2015๋…„ 12์›” 22์ผ  ยท  64์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: feathersjs/feathers

ํ˜„์žฌ ์œ ํšจํ•œ ์ธ์ฆ ํ† ํฐ์„ <loginEndpoint>/refresh ์— ๊ฒŒ์‹œํ•˜์—ฌ ์ƒˆ ํ† ํฐ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์•ฝ๊ฐ„ ๋‹ค๋ฅธ ์›Œํฌํ”Œ๋กœ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
https://auth0.com/learn/refresh-tokens

Authentication Feature

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์ด ๊ธฐ๋Šฅ์€ React Native ์•ฑ๊ณผ ๊ด€๋ จํ•˜์—ฌ MUST์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์ฒ˜์Œ์— ๋กœ๊ทธ์ธํ•˜๊ณ  ๋ช‡ ์ฃผ ํ›„์— ์•ฑ์„ ์—ด๋ฉด ์—ฌ์ „ํžˆ ๋กœ๊ทธ์ธ๋˜์–ด ์žˆ์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  64 ๋Œ“๊ธ€

:+1: @corymsmith ์™€ ๋‚˜๋Š” ์ด๊ฒƒ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. "ํœด๊ฐ€"๋ฅผ ํ†ตํ•ด ๊ฒฐ์Šน์„ ์„ ๋„˜์–ด ์ด๊ฒƒ์„ ๊ฑท์–ด์ฐจ๋„๋ก ๋•๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๋งˆ์Šคํ„ฐ์—์„œ ์ง€์›ํ•˜์ง€๋งŒ decoupling ๋ธŒ๋žœ์น˜์—์„œ๋„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ํ† ํฐ์„ ์ƒˆ๋กœ ๊ณ ์น˜๋ ค๋ฉด ๋‘ ๊ฐ€์ง€ ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ์ด๋ฉ”์ผ/๋น„๋ฐ€๋ฒˆํ˜ธ, ํŠธ์œ„ํ„ฐ ๋“ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์žฌ์ธ์ฆํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  2. ์œ ํšจํ•œ ํ† ํฐ์„ GET /auth/token/refresh ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ† ํฐ ๊ฐฑ์‹  ํ”„๋กœ์„ธ์Šค๊ฐ€ ์žˆ์ง€๋งŒ ์œ„์— ๊ฒŒ์‹œํ•œ Auth0 ๋งํฌ์— ์„ค๋ช…๋œ ๊ฒƒ์ฒ˜๋Ÿผ ์™„์ „ํ•œ ๊ฐฑ์‹  ํ† ํฐ ์ง€์›์€ ์•„๋‹™๋‹ˆ๋‹ค. ์‹ค์ œ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์€ GitHub ์ธ์ฆ ์ฝ”๋“œ/๋น„๋ฐ€๋ฒˆํ˜ธ์™€ ์œ ์‚ฌํ•˜๊ฒŒ ์ž‘๋™ํ•˜์ง€๋งŒ ์ƒˆ JWT ํ† ํฐ์„ ์–ป๋Š” ๋ฐ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ JWT ํ† ํฐ์ด ๋งŒ๋ฃŒ๋˜๋”๋ผ๋„ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์ด ์žˆ์œผ๋ฉด ์ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์‹œ ๋กœ๊ทธ์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. userId๊ฐ€ ๊ทธ๋Œ€๋กœ ์œ ์ง€๋˜๊ณ  ์–ธ์ œ๋“ ์ง€ ์ทจ์†Œ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ ์–ด๋„ ๊ทธ๊ฒƒ์ด ๋‚ด๊ฐ€ Auth0 ๊ธฐ์‚ฌ์—์„œ ์ˆ˜์ง‘ํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์•„ ๋งž๋‹ค @marshallswain. ๋งํฌ๋ฅผ ํด๋ฆญํ–ˆ์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค :wink:

๋‚˜๋Š” ์ฒซ ๋ฒˆ์งธ ์ปท์„ ์œ„ํ•ด ์ด๊ฒƒ์„ 1.0 ์ด์ •ํ‘œ์—์„œ ๋‚จ๊ฒจ ๋‘˜ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์ด ๋‹ค์‹œ ์ธ์ฆํ•˜๋Š” ๊ฒƒ์€ ์‰ฝ์Šต๋‹ˆ๋‹ค.

์ €๋Š” ์ด๊ฒƒ์„ feathers-authentication 2.0์œผ๋กœ ๋งŒ๋“œ๋Š” ๊ฒƒ์— ํˆฌํ‘œํ•ฉ๋‹ˆ๋‹ค.

์ข‹์€ ๋งˆ์Œ.

์ธ์ฆ ์›Œํฌํ”Œ๋กœ๊ฐ€ ์ •ํ™•ํžˆ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ๋ช…ํ™•ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ์ „ํžˆ ํ˜ผ๋ž€์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค.

์ง€๊ธˆ ํ•˜๊ณ  ์žˆ๋Š” ์ผ์€.
1.) ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์‚ฌ์šฉ์ž ์ด๋ฆ„ ๋ฐ ์•”ํ˜ธ๋ฅผ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

 curl -X POST https://xxx/auth/local   -H "Content-Type: application/json"   -d '{ "email":"xxx", "password":"yyy"}'

์ด๊ฒƒ์€ JWT ํ† ํฐ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJfaWQiOiI1NzhhNjUyN2RkMTZiMjIwMDRhY2ZjNmEiLCJpYXQiOjE0NzAzMjYyODUsImV4cCI6MTQ3MDQxMjY4NSwiaXNzIjoiZmVhdGhlcnMifQ.OVvQbnxfoDGxPFm3Y6tBhRae2Qa6_mDq-PVIo8RcC8Y"}

2.) ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ด ํ† ํฐ์„ Authorizatin http ํ—ค๋”์— ๋„ฃ์–ด API์— ์•ก์„ธ์Šคํ•ฉ๋‹ˆ๋‹ค.

curl -X GET https://xxx/users  -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJfaWQiOiI1NzhhNjUyN2RkMTZiMjIwMDRhY2ZjNmEiLCJpYXQiOjE0NzAzMjU1NzYsImV4cCI6MTQ3MDQxMTk3NiwiaXNzIjoiZmVhdGhlcnMifQ._CHdx3RpEuI189t90mXq-IMPXRNuoVh7nBwY1ON7xCY'

๋‚ด๊ฐ€ ์ดํ•ดํ•˜์ง€ ๋ชปํ•˜๋Š” ๊ฒƒ์€ ์ด ํ† ํฐ์„ ์‹ค์ œ๋กœ ์ƒˆ๋กœ ๊ณ ์น˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.
๋‚ด๊ฐ€ ์‹œ๋„ํ•œ ๊ฒƒ์€ ์ด ํ† ํฐ์„ xxx/auth/token/refresh๋กœ ๋ณด๋‚ด๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๋‚ด๊ฐ€ ์–ป์€ ๊ฒƒ์€ ๋˜ ๋‹ค๋ฅธ ๋งค์šฐ ๊ธด ํ† ํฐ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ด์ „ ํ† ํฐ๊ณผ ์ƒˆ ํ† ํฐ์„ ๋ชจ๋‘ ์‚ฌ์šฉํ•˜์—ฌ API์— ์•ก์„ธ์Šคํ•˜๋ ค๊ณ  ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‘˜ ๋‹ค ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค ... (์ด์ „ ๊ฒƒ์„ ๋น„ํ™œ์„ฑํ™”ํ•ด์•ผํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ?)

curl -X GET https://xxx/auth/token/refresh  -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJfaWQiOiI1NzhhNjUyN2RkMTZiMjIwMDRhY2ZjNmEiLCJpYXQiOjE0NzAzMjU1NzYsImV4cCI6MTQ3MDQxMTk3NiwiaXNzIjoiZmVhdGhlcnMifQ._CHdx3RpEuI189t90mXq-IMPXRNuoVh7nBwY1ON7xCY'
{"query":{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJfaWQiOiI1NzhhNjUyN2RkMTZiMjIwMDRhY2ZjNmEiLCJpYXQiOjE0NzAzMjU1NzYsImV4cCI6MTQ3MDQxMTk3NiwiaXNzIjoiZmVhdGhlcnMifQ._CHdx3RpEuI189t90mXq-IMPXRNuoVh7nBwY1ON7xCY"},"provider":"rest","token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJxdWVyeSI6eyJ0b2tlbiI6ImV5SjBlWEFpT2lKS1YxUWlMQ0poYkdjaU9pSklVekkxTmlKOS5leUpmYVdRaU9pSTFOemhoTmpVeU4yUmtNVFppTWpJd01EUmhZMlpqTm1FaUxDSnBZWFFpT2pFME56QXpNalUxTnpZc0ltVjRjQ0k2TVRRM01EUXhNVGszTml3aWFYTnpJam9pWm1WaGRHaGxjbk1pZlEuX0NIZHgzUnBFdUkxODl0OTBtWHEtSU1QWFJOdW9WaDduQndZMU9ON3hDWSJ9LCJwcm92aWRlciI6InJlc3QiLCJ0b2tlbiI6ImV5SjBlWEFpT2lKS1YxUWlMQ0poYkdjaU9pSklVekkxTmlKOS5leUpmYVdRaU9pSTFOemhoTmpVeU4yUmtNVFppTWpJd01EUmhZMlpqTm1FaUxDSnBZWFFpT2pFME56QXpNalUxTnpZc0ltVjRjQ0k2TVRRM01EUXhNVGszTml3aWFYTnpJam9pWm1WaGRHaGxjbk1pZlEuX0NIZHgzUnBFdUkxODl0OTBtWHEtSU1QWFJOdW9WaDduQndZMU9ON3hDWSIsImRhdGEiOnsiX2lkIjoiNTc4YTY1MjdkZDE2YjIyMDA0YWNmYzZhIiwiaWF0IjoxNDcwMzI1NTc2LCJleHAiOjE0NzA0MTE5NzYsImlzcyI6ImZlYXRoZXJzIiwidG9rZW4iOiJleUowZVhBaU9pSktWMVFpTENKaGJHY2lPaUpJVXpJMU5pSjkuZXlKZmFXUWlPaUkxTnpoaE5qVXlOMlJrTVRaaU1qSXdNRFJoWTJaak5tRWlMQ0pwWVhRaU9qRTBOekF6TWpVMU56WXNJbVY0Y0NJNk1UUTNNRFF4TVRrM05pd2lhWE56SWpvaVptVmhkR2hsY25NaWZRLl9DSGR4M1JwRXVJMTg5dDkwbVhxLUlNUFhSTnVvVmg3bkJ3WTFPTjd4Q1kifSwiaWF0IjoxNDcwMzI2NDQyLCJleHAiOjE0NzA0MTI4NDIsImlzcyI6ImZlYXRoZXJzIn0.TqUv3051TTGbX4cPfkN-6pOOB5SN9nH-E7TU1HHSsb8","data":{"_id":"578a6527dd16b22004acfc6a","iat":1470325576,"exp":1470411976,"iss":"feathers","token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJfaWQiOiI1NzhhNjUyN2RkMTZiMjIwMDRhY2ZjNmEiLCJpYXQiOjE0NzAzMjU1NzYsImV4cCI6MTQ3MDQxMTk3NiwiaXNzIjoiZmVhdGhlcnMifQ._CHdx3RpEuI189t90mXq-IMPXRNuoVh7nBwY1ON7xCY"}}

๋” ์ด์ƒํ•œ ์ ์€ ์ด ์ƒˆ ํ† ํฐ์„ ์‚ฌ์šฉํ•˜์—ฌ /auth/token/refresh๋กœ ๋‹ค์‹œ ๋ณด๋‚ด๋ ค๊ณ  ํ–ˆ์Šต๋‹ˆ๋‹ค.
๋‚˜๋Š” ์ด๊ฒƒ๋ณด๋‹ค ๋” ๊ธด ํ† ํฐ์„ ์–ป์—ˆ๋‹ค.

์—ฌ๊ธฐ์„œ ๋‚ด๊ฐ€ ๋ฌด์—‡์„ ์ž˜๋ชปํ–ˆ๊ฑฐ๋‚˜ ์˜คํ•ดํ–ˆ๋Š”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ œ์•ˆํ•˜์‹ญ์‹œ์˜ค.

@parnurzeal ์šฐ๋ฆฌ๋Š” ์•„์ง ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์ œ์•ˆ๋œ ๊ธฐ๋Šฅ์ธ ์ด์œ ์ž…๋‹ˆ๋‹ค.

์ƒˆ ํ† ํฐ์„ ์–ป๋Š” ๋ฐฉ๋ฒ•์€ ๊ธฐ์กด์˜ ์œ ํšจํ•œ JWT๋กœ /auth/token ๋Œ€ํ•œ POST๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ์ธ์ฆ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๋กœ๊ทธ์ธํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹น์‹ ์€ ๋ชจ๋“  ๊ฒƒ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒํ•˜๊ณ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๊ทธ๋ ‡๊ธด ํ•œ๋ฐ ์ œ๊ฐ€ ์–ด๋–ป๊ฒŒ ํ–ˆ๋Š”์ง€, ์–ด๋–ค ๊ฒฐ๊ณผ๋ฅผ ์–ป์—ˆ๋Š”์ง€ ์ž˜ ๋ด์ฃผ์„ธ์š”.

์‰ฌ์šด ์˜ˆ๋ฅผ ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
abcdefghijklmno ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ ํ† ํฐ์„ ์š”์ฒญํ•  ๋•Œ(๋‹จ์ง€ ์ž„์˜์˜ ๋ง๋„ ์•ˆ๋˜๋Š” ํ† ํฐ).
์‘๋‹ต ๋ฐฑ์€ ์ด์ „ ํ† ํฐ์˜ ๋” ๊ธด ๋ฒ„์ „์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. -> abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์‹œ ์‹œ๋„ํ•˜๋ฉด ๋” ๊ธด ๋ฒ„์ „์„ ์–ป๊ฒŒ ๋ฉ๋‹ˆ๋‹ค ->
abcdefghijklmnopqrstuvwxyz1234567890 ๋ฐ ๋ฃจํ”„๊ฐ€ ๊ณ„์†๋ฉ๋‹ˆ๋‹ค(๋” ๋งŽ์ด ์š”์ฒญํ•˜๋ฉด ์ด์ „ ๋ฒ„์ „์˜ ๋” ๊ธด ๋ฒ„์ „์„ ์–ป์Œ).

๋˜ํ•œ ์œ„์˜ ์„ธ ๊ฐ€์ง€ ํ† ํฐ์„ ๋ชจ๋‘ ๋™์‹œ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ƒˆ ํ† ํฐ์„ ์š”์ฒญํ•œ ํ›„ ์ด์ „ ํ† ํฐ์ด ๋งŒ๋ฃŒ๋˜์–ด์•ผ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ?

@parnurzeal ๋‚ด ๋ง์€ ๊ทธ ๊ธฐ๋Šฅ์ด ์‹ค์ œ๋กœ ๊ตฌํ˜„๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‹น์‹ ์ด ํ•œ ์ผ์„ ํ•˜์ง€ ๋ง๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ตฌํ˜„(์ง€๊ธˆ๊นŒ์ง€)์— ๋”ฐ๋ฅด๋ฉด /auth/token/refresh ๋„๋‹ฌํ•  ๋•Œ๋งˆ๋‹ค ํ† ํฐ์ด ๊ณ„์† ์ฆ๊ฐ€ํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์€ ๋ฐ์ดํ„ฐ๋ฅผ ํ† ํฐ์— ๋‹ค์‹œ ๋ฐ€์–ด๋„ฃ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ž‘๋™ํ•˜๋„๋ก ์˜๋„๋œ ๋ฐฉ์‹์ด ์•„๋‹ˆ๋ฉฐ ์™„๋ฃŒํ•  ์‹œ๊ฐ„์ด ์—†์—ˆ์œผ๋ฉฐ ์ด๊ฒƒ์ด ๋ฌธ์„œํ™”๋˜์ง€ ์•Š์€ ์ด์œ ์ž…๋‹ˆ๋‹ค. ๋‹น์‹ ์€ ๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•ด์„œ๋Š” ์•ˆ๋ฉ๋‹ˆ๋‹ค.

์ƒˆ ํ† ํฐ์„ ์š”์ฒญํ•œ ํ›„ ์ด์ „ ํ† ํฐ์ด ๋งŒ๋ฃŒ๋˜์–ด์•ผ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ?

์ด๊ฒƒ์ด JWT์˜ ํŠน์„ฑ์ž…๋‹ˆ๋‹ค. TTL์—์„œ ์ž์ฒด์ ์œผ๋กœ ๋งŒ๋ฃŒ๋ฉ๋‹ˆ๋‹ค. ์•„์ง ๋งŒ๋ฃŒ๋˜์ง€ ์•Š์€ ์˜ค๋ž˜๋œ ํ† ํฐ์ด ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๋ ค๋ฉด ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ๋ฅผ ์œ ์ง€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ ์ด๊ฒƒ์€ ์—ฌ๋Ÿฌ๋ถ„์—๊ฒŒ ๋‹ฌ๋ ค ์žˆ์œผ๋ฉฐ ์ด์— ๋Œ€ํ•œ ๋ฏธํ•ด๊ฒฐ ๋ฌธ์ œ(#133)๊ฐ€ ์žˆ์ง€๋งŒ ๊ณง (๋งŒ์•ฝ ์žˆ๋‹ค๋ฉด) ํ•ด๊ฒฐ๋˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š”, ์ €๋Š” /auth/refresh/token์„ ์กฐ์‚ฌํ–ˆ๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค.

...
function pick (o, ...props) {
  return Object.assign({}, ...props.map(prop => ({[prop]: o[prop]})));
}

// Provider specific config
const defaults = {
  payload: ['id', 'role'],
  passwordField: 'password',
  issuer: 'feathers',
  algorithm: 'HS256',
  expiresIn: '1d', // 1 day
};
...
// GET /auth/token/refresh
  get (id, params) {
    if (id !== 'refresh') {
      return Promise.reject(new errors.NotFound());
    }

    const options = this.options;

    // Add payload fields
    const data = pick(params.payload, options.payload);

    return new Promise(resolve => {
      jwt.sign(data, config.get('auth').token.secret, options, token => {
        return resolve({token: token});
      });
    });

  }

๊ตฌํ˜„์ด ๋„ˆ๋ฌด ์ˆœ์ง„ํ•œ๊ฐ€์š”? ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ ์—ฐ๋งˆ๋ฅผ ์‹œ๋„ํ•˜๊ณ  ๋ช‡ ๊ฐ€์ง€ ํ…Œ์ŠคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  PR์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@aboutlo ๋…ธ๋ ฅ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค! v0.8์ด ์ถœ์‹œ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์Šต๋‹ˆ๋‹ค(์ง€๊ธˆ์€ ์•ŒํŒŒ ์ƒํƒœ์ž„). ๋งŽ์€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์žˆ๊ณ  ์ด๋ฒˆ ์ฃผ์— ํ•ด๋‹น ๊ฒฝ๋กœ๊ฐ€ ์‚ฌ๋ผ์งˆ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
์ €๋Š” ์˜ค๋Š˜ ๋ฒ ํƒ€ ๋ฆด๋ฆฌ์Šค๋ฅผ ์ค‘๋‹จํ•˜๊ณ  ํ˜„์žฌ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๊ฐ€์ด๋“œ๋ฅผ ๋งˆ๋ฌด๋ฆฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ธธ์ง€ ์•Š์„ ๊ฒƒ์ด๋ฉฐ v0.8์€ ์ธ์ฆ๊ณผ ๊ด€๋ จ๋œ ๋งŽ์€ ํ˜„์žฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ํ† ํฐ์„ ์ƒˆ๋กœ ๊ณ ์นจํ•˜๊ธฐ ์œ„ํ•ด ๋งŽ์€ ์ƒ๊ฐ์„ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— 0.8์ด ์ถœ์‹œ๋˜๋ฉด(์ด๋ฒˆ ์ฃผ) ์ด ๋ฌธ์ œ์— ๋Œ€ํ•ด ๋…ผ์˜ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ์ฃผ ํ›„๋ฐ˜์— ์˜ˆ๋น„์ ์ธ ์ƒ๊ฐ์„ ํ•˜๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ถฉ๋ถ„ํžˆ ๊ณต์ •ํ•œ @ekryski , ๋‚˜๋Š” 0.8์„ ๊ธฐ๋‹ค๋ฆด ๊ฒƒ์ž…๋‹ˆ๋‹ค :)

์ด ๊ธฐ๋Šฅ์€ React Native ์•ฑ๊ณผ ๊ด€๋ จํ•˜์—ฌ MUST์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์ฒ˜์Œ์— ๋กœ๊ทธ์ธํ•˜๊ณ  ๋ช‡ ์ฃผ ํ›„์— ์•ฑ์„ ์—ด๋ฉด ์—ฌ์ „ํžˆ ๋กœ๊ทธ์ธ๋˜์–ด ์žˆ์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค.

@deiucanta ์ข‹์€ ์†Œ์‹์€ [email protected] ์„ ์„ค๊ณ„ํ•˜๋Š” ๋™์•ˆ ์ด ๊ธฐ๋Šฅ์„ ์—ผ๋‘์—

์ข‹์€ ์†Œ์‹์ž…๋‹ˆ๋‹ค! ๐Ÿ‘ ๊ธฐ๋Œ€๋ฉ๋‹ˆ๋‹ค

@marshallswain ์ด ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค. ์–ธ์ œ ์˜ˆ์ƒ๋˜๋Š”์ง€ ์•Œ๋ ค์ฃผ์„ธ์š”. ์•„๋‹ˆ๋ฉด ์ด๋ฏธ ์ถœ์‹œ๋œ๊ฑด๊ฐ€์š”? ๋ฏธ๋ฆฌ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

@deiucanta ๊ทธ๋™์•ˆ ์ด ๊ธฐ๋Šฅ์ด ์ถœ์‹œ๋  ๋•Œ๊นŒ์ง€ ์ˆ˜๋ช…์ด ๋” ๊ธด ํ† ํฐ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ด์ œ๋˜๋ฉด ์ธ์ฆ ์•”ํ˜ธ๋ฅผ ์ƒˆ ๊ฐ’์œผ๋กœ ๊ต์ฒดํ•˜์—ฌ ๊ธฐ์กด ์„ธ์…˜์„ ๋ชจ๋‘ ์ง€์šฐ๊ณ  ๋ชจ๋“  ์‚ฌ์šฉ์ž๊ฐ€ ๋” ์งง์€ ๊ฐฑ์‹  ์„ธ์…˜์„ ์‚ฌ์šฉํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@atulrpandey ์ •์‹ ์ถœ์‹œ๋Š” ์•„๋‹ˆ์ง€๋งŒ ๊ตฌํ˜„ํ•˜๊ธฐ๋„ ์–ด๋ ต์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ƒˆ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ์ƒ์„ฑํ•˜๊ณ  DB์˜ ์‚ฌ์šฉ์ž ๊ฐœ์ฒด์— ์ €์žฅํ•˜๋Š” ํ›„ํฌ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ์‚ฌ์šฉ๋˜๊ฑฐ๋‚˜ ๋งŒ๋ฃŒ๋˜๋ฉด ์‚ฌ์šฉ์ž์—๊ฒŒ์„œ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

@pettermikitsh ๋‹น์‹ ์ด ํ•  ์ˆ˜์žˆ๋Š” ๋˜ ๋‹ค๋ฅธ ์ผ์€ (๋ชจ๋ฐ”์ผ์—์žˆ๋Š” ๊ฒฝ์šฐ) clientId ๋ฐ clientSecret ํด๋ผ์ด์–ธํŠธ์— ์•ˆ์ „ํ•˜๊ฒŒ ์ €์žฅํ•˜๊ณ  JWT accessToken์ด ๋งŒ๋ฃŒ๋˜๋ฉด ๋‹ค์‹œ ์ธ์ฆํ•˜์‹ญ์‹œ์˜ค.

@ekryski ์ด๋Ÿฌํ•œ ์ „๋žต ์ค‘ ํ•˜๋‚˜์˜ ์˜ˆ๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์ •๋ง ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์•„๋‹ˆ๋ฉด ๊ณต์‹ ์ง€์›์ด ํ’€๋ฆฌ๋Š” ๋ฐ ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋‚˜์š”? ์ด๊ฒƒ์€ ๋ชจ๋ฐ”์ผ ์ธ์ฆ์— ์ •๋ง ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค!

์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ ์ฃผ์ œ:

์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์€ ์ƒˆ ์•ก์„ธ์Šค ํ† ํฐ์„ ์–ป๋Š” ๋ฐ ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ํŠน์ • ๋ฆฌ์†Œ์Šค์— ์•ก์„ธ์Šคํ•˜๊ธฐ ์œ„ํ•ด ์•ก์„ธ์Šค ํ† ํฐ์ด ํ•„์š”ํ•  ๋•Œ๋งˆ๋‹ค ํด๋ผ์ด์–ธํŠธ๋Š” ์ธ์ฆ ์„œ๋ฒ„์—์„œ ๋ฐœ๊ธ‰ํ•œ ์ƒˆ ์•ก์„ธ์Šค ํ† ํฐ์„ ์–ป๊ธฐ ์œ„ํ•ด ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์ธ ์‚ฌ์šฉ ์‚ฌ๋ก€์—๋Š” ์ด์ „ ์•ก์„ธ์Šค ํ† ํฐ์ด ๋งŒ๋ฃŒ๋œ ํ›„ ์ƒˆ ์•ก์„ธ์Šค ํ† ํฐ์„ ์–ป๊ฑฐ๋‚˜ ์ƒˆ ๋ฆฌ์†Œ์Šค์— ์ฒ˜์Œ์œผ๋กœ ์•ก์„ธ์Šคํ•˜๋Š” ๊ฒƒ์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ๋„ ๋งŒ๋ฃŒ๋  ์ˆ˜ ์žˆ์ง€๋งŒ ์˜คํžˆ๋ ค ์˜ค๋ž˜ ์ง€์†๋ฉ๋‹ˆ๋‹ค. ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์œ ์ถœ๋˜์ง€ ์•Š๋„๋ก ์—„๊ฒฉํ•œ ์ €์žฅ ์š”๊ตฌ ์‚ฌํ•ญ์ด ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ธ์ฆ ์„œ๋ฒ„์—์„œ ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ ์— https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/

๊ทธ๋ž˜์„œ ์ƒ๊ฐ๋ณด๋‹ค ๋นจ๋ฆฌ React Native์— ์ž…๋ฌธํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ์„ ๊ธฐ์—ฌํ•  ์ˆ˜ ์žˆ์„์ง€ ์ƒ๊ฐํ•˜๊ณ  ์žˆ์ง€๋งŒ ๊ทธ๊ฒƒ์ด ์˜ฌ๋ฐ”๋ฅธ ๊ตฌํ˜„์ธ์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์™„์ „ํžˆ ์ดํ•ดํ•˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์€ ์ƒํƒœ ๋น„์ €์žฅ์ด ์•„๋‹ˆ๋ฏ€๋กœ ์‚ฌ์šฉ์— ๋ช‡ ๊ฐ€์ง€ ์ œ์•ฝ์ด ์žˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: ๊ฐœ๋ฐœ์ž๊ฐ€ ์ €์žฅ์†Œ ์–ด๋Œ‘ํ„ฐ๋ฅผ ์ œ๊ณตํ•ด์•ผ ํ•จ).

์œ ํšจํ•œ JWT๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ์ธ์ฆ ์‘๋‹ต์—์„œ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์ด ์ž๋™์œผ๋กœ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๊นŒ(์˜ˆ: accessToken )? Auth0์ด https://auth0.com/learn/refresh-tokens/ ์˜ ์˜ˆ์—์„œ ์ธ์ฆ ์‘๋‹ต( accessToken ๋ฐ refreshToken )์— ์ด๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค .

@pettermikitsh ์œ ํšจํ•œ JWT๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ์–ป์„ ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ˆ„๊ตฌ๋‚˜ JWT๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๊ณ  ๊ณ„์ •์— ๊ณ„์† ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ๋กœ๊ทธ์ธ/๊ฐ€์ž… ์‘๋‹ต๊ณผ ํ•จ๊ป˜ ๋ฐ˜ํ™˜๋˜๋ฉฐ ํด๋ผ์ด์–ธํŠธ๋Š” ๋‹ค์‹œ ๋กœ๊ทธ์ธ/๊ฐ€์ž…ํ•˜์—ฌ ์ƒˆ ์„ธ์…˜๊ณผ ์ƒˆ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š” ํ•œ ํŠน์ • ์„ธ์…˜์— ๋Œ€ํ•ด ๋‹ค์‹œ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์€ ์‹ค์ œ๋กœ ๋งŒ๋ฃŒ๋  ํ•„์š”๊ฐ€ ์—†์ง€๋งŒ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅ๋˜๋Š” ๊ฒฝ์šฐ ํ˜ธ์ถœ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์‚ฌ์šฉ์ž๋Š” ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์œผ๋กœ ์–ผ๋งˆ๋‚˜ ๋งŽ์€ ํ™œ์„ฑ ์„ธ์…˜์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ๋ฐœํ–‰ํ•  ๋•Œ ๋” ๋งŽ์€ ์ •๋ณด๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: os, ip, ์žฅ์น˜ ์ด๋ฆ„ ๋“ฑ).

์ ์–ด๋„ ์ €๋Š” ๊ทธ๋ ‡๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ๋ฐœ๊ธ‰ํ•  ๋•Œ์™€ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•  ๋•Œ ์ธ์ฆ์„ ํ™•์ธํ•˜๋Š” ํ•œ ์œ ํšจํ•œ JWT๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

@marshallswain

ํ˜„์žฌ ์œ ํšจํ•œ ์ธ์ฆ ํ† ํฐ์„ <loginEndpoint>/refresh ์— ๊ฒŒ์‹œํ•˜์—ฌ ์ƒˆ ํ† ํฐ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์—๋Š” ์•ฝ๊ฐ„ ๋‹ค๋ฅธ ์›Œํฌํ”Œ๋กœ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค...

๋”ฐ๋ผ์„œ ํ˜ผ๋™์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด refresh ๊ฐ€ ์•„๋‹Œ renew ๋ถˆ๋Ÿฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. <loginEndpoint>/renew

@abhishekbhardwaj๊ฐ€ ๋งํ–ˆ๋“ฏ์ด

accessToken์€ accessToken์œผ๋กœ ์ƒˆ๋กœ ๊ณ ์น  ์ˆ˜ ์—†๊ณ  refresehToken ๋˜๋Š” ์‚ฌ์šฉ์ž ์ด๋ฆ„/๋น„๋ฐ€๋ฒˆํ˜ธ๋กœ๋งŒ ์ƒˆ๋กœ ๊ณ ์น  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ธ์ฆ...

ํ˜„์žฌ ๋‹ค์Œ๊ณผ ๊ฐ™์ด accessToken์„ ์‚ฌ์šฉํ•˜์—ฌ accessToken์„ ์ƒˆ๋กœ ๊ณ ์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

https://github.com/feathersjs/authentication-jwt/issues/61

๋˜ ๋‹ค๋ฅธ ์ ‘๊ทผ ๋ฐฉ์‹์€ accessToken์˜ ํŽ˜์ด๋กœ๋“œ ๋‚ด๋ถ€์— ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ์ €์žฅํ•œ ๋‹ค์Œ ํ˜„์žฌ ์ƒˆ๋กœ ๊ณ ์นจ API๊ฐ€ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์ด ์ทจ์†Œ๋˜์ง€ ์•Š์•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค(๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋˜๋Š” redis ํ˜ธ์ถœ์„ ํ†ตํ•ด). ์ด ๋ฐฉ๋ฒ•์œผ๋กœ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์€ ๊ฐ„๋‹จํ•œ ์ž๋™ ์ฆ๊ฐ€ ID๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ƒˆ๋กœ ๊ณ ์นจ API๋Š” ๋” ์ด์ƒ ๋งŒ๋ฃŒ๋ฅผ ํ™•์ธํ•˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ฐฑ์‹  ํ† ํฐ(๋‹จ์ˆœ ์ •์ˆ˜)์€ ์•ก์„ธ์Šค ํ† ํฐ์œผ๋กœ ์„œ๋ช…๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค.

์ด ๋ฐฉ๋ฒ•์€ ํ˜„์žฌ ์ฝ”๋“œ ๊ธฐ๋ฐ˜์— ๋Œ€ํ•œ ๋ณ€๊ฒฝ์„ ์ตœ์†Œํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ƒˆ๋กœ ๊ณ ์นจ API์˜ ๊ฒฝ์šฐ ์‚ฌ์šฉ์ž๊ฐ€ ์•ก์„ธ์Šค ํ† ํฐ์ด ์ทจ์†Œ๋˜์ง€ ์•Š์•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค(ํŽ˜์ด๋กœ๋“œ ๋‚ด๋ถ€์˜ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ ํ™•์ธ์„ ํ†ตํ•ด). ์ด ํ›„ํฌ๊ฐ€ ์ œ๊ณต๋˜๋ฉด t ๋” ์ด์ƒ ๋งŒ๋ฃŒ ์‹œ๊ฐ„์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

@arash16์—์„œ ์ด ์ ‘๊ทผ ๋ฐฉ์‹์„ ์ข€ ๋” ์„ค๋ช…ํ•ด

accessTokens ํŽ˜์ด๋กœ๋“œ์— ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ์ €์žฅํ•˜๊ณ  ์ƒˆ๋กœ ๊ณ ์นจ API๊ฐ€ ๋งŒ๋ฃŒ๋ฅผ ํ™•์ธํ•˜์ง€ ์•Š์œผ๋ฉด ๋ชจ๋“  accessToken์„ "๋น„๋งŒ๊ธฐ"๋กœ ํšจ๊ณผ์ ์œผ๋กœ ๋งŒ๋“ค์ง€ ์•Š์•˜์Šต๋‹ˆ๊นŒ?

๋ชจ๋“  accessToken์„ ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ ์•ก์„ธ์Šค ํ† ํฐ์„ ์–ป์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋งž์Šต๋‹ˆ๊นŒ?

๋‚ด๊ฐ€ ๋ญ”๊ฐ€๋ฅผ ๋†“์น˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

@BigAB
๋‚˜๋Š” refresh api ์— ๋Œ€ํ•ด์„œ๋งŒ ๋งŒ๋ฃŒ๋ฅผ ํ™•์ธํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ–ˆ์Šต๋‹ˆ๋‹ค. ๋™์ผํ•œ accessToken์ด refresh-token๊ณผ access-token์œผ๋กœ ๋ชจ๋‘ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด ํ† ํฐ์€ ์ƒˆ๋กœ๊ณ ์นจํ•˜๊ณ  ์ƒˆ ์•ก์„ธ์Šค ํ† ํฐ์„ ์–ป๋Š” ๊ฒฝ์šฐ์—๋งŒ ๋งŒ๋ฃŒ๋˜์ง€ ์•Š์œผ๋ฉฐ, ์‚ฌ์šฉ์ž๊ฐ€ ์ˆ˜๋™์œผ๋กœ refresh-id ์ž์ฒด๋ฅผ

๊ฐœ๋ฐœ์ž๋Š” ๋ชจ๋“  ์ƒˆ๋กœ ๊ณ ์นจ ID๋ฅผ ์ €์žฅํ•  db-table/redis๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์ผ๋ถ€(๋˜๋Š” ๋ชจ๋“ ) ๋‹ค๋ฅธ ์„ธ์…˜์—์„œ ์ทจ์†Œํ•˜๊ฑฐ๋‚˜ ๋กœ๊ทธ์•„์›ƒํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ๋ชจ๋“  ์ƒˆ๋กœ ๊ณ ์นจ ID ๋ชฉ๋ก(๋ธŒ๋ผ์šฐ์ € ๋˜๋Š” ์ƒ์„ฑ ๋‚ ์งœ ๋“ฑ๊ณผ ๊ฐ™์€ ๊ธฐํƒ€ ์ถ”๊ฐ€ ์ •๋ณด ํฌํ•จ)์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์‚ฌ์šฉ์ž๋Š” ์ œ๊ฑฐ(์„œ๋ช… - ๋ฐ–์œผ๋กœ) ์„ ํƒ์ ์œผ๋กœ. ๊ทธ๋Ÿฐ ๋‹ค์Œ ํ•ด๋‹น ์ƒˆ๋กœ ๊ณ ์นจ ID๋ฅผ ํฌํ•จํ•˜๋Š” ์‹ค์ œ ํ† ํฐ์ด ๋งŒ๋ฃŒ๋˜๋ฉด ์ƒˆ๋กœ ๊ณ ์นจ API๊ฐ€ ์ƒˆ ํ† ํฐ ์ œ๊ณต์„ ๊ฑฐ๋ถ€ํ•ฉ๋‹ˆ๋‹ค.

ํ† ํฐ ๋‚ด๋ถ€์˜ refresh-id๋Š” ๋Œ€๋ถ€๋ถ„ ์‚ฌ์šฉ๋˜์ง€ ์•Š์œผ๋ฉฐ ํ† ํฐ์ด ๋งŒ๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ถŒํ•œ ๋ถ€์—ฌ๊ฐ€ ์ƒํƒœ ๋น„์ €์žฅ์ž…๋‹ˆ๋‹ค.

์•ก์„ธ์Šค ํ† ํฐ์˜ ๋งŒ๋ฃŒ ์‹œ๊ฐ„์€ ์งง์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ(10๋ถ„ ๋ฏธ๋งŒ) ์‚ฌ์šฉ์ž๋Š” ํŽ˜์ด์ง€๋ฅผ ๋‹ซ๊ณ  ์ž๋ฆฌ๋ฅผ ๋œฐ ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋‚˜์ค‘์— ํŽ˜์ด์ง€๋ฅผ ์—ด๋ฉด ์•ก์„ธ์Šค ํ† ํฐ์ด ์ด๋ฏธ ๋งŒ๋ฃŒ๋˜์–ด ๋กœ๊ทธ์•„์›ƒ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ† ํฐ ๋‚ด๋ถ€์˜ refresh-id๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ์ˆ˜๋ช… ์ด ํ›จ์”ฌ

๋ณด์•ˆ ๊ด€์ ์—์„œ ์ด ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์•ก์„ธ์Šค ํ† ํฐ์€ ์ด์ „ ์„ธ์…˜ ํ‚ค์ฒ˜๋Ÿผ ์ทจ๊ธ‰๋˜์–ด์•ผ ํ•˜๋ฉฐ, ๋งค๋ฒˆ(๋งŒ๋ฃŒ๋œ ํ•œ ๋ฒˆ๋งŒ) ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ํ˜ธ์ถœํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค๋Š” ์ถ”๊ฐ€ ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

@ arash16 , ์•ก์„ธ์Šค JWT ๋‚ด๋ถ€์— ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ์ €์žฅํ•˜๋Š” ์•„์ด๋””์–ด๊ฐ€ ์ข‹์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์ธก์—์„œ ์ด ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ๊ฒ€์ƒ‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์˜ˆ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

๋‚ด ํ˜„์žฌ ๋ฌธ์ œ: ์•ก์„ธ์Šค ํ† ํฐ์ด ๋งŒ๋ฃŒ๋˜๋ฉด ํŽ˜๋”์˜ ํ›„ํฌ ์ปจํ…์ŠคํŠธ์—์„œ ํŽ˜์ด๋กœ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. @feathersjs/authentication ํŒจํ‚ค์ง€์˜ verifyJWT() ์œ ํ‹ธ๋ฆฌํ‹ฐ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด app.service('authentication').hooks({ before: { create: ... } }) ์˜ ๋งจ ์ฒ˜์Œ์— ?

์ง€๊ธˆ ๊นƒํ„ธ์— ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ์‚ฌ์šฉํ•˜๋Š” ์ฃผ์˜๊นŠ์€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๊ทธ๋“ค์— ๋Œ€ํ•œ ์ง€์›์„ ์ถ”๊ฐ€ํ•  ๊ณ„ํš์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๋ชจ๋‘๋“ค ์•ˆ๋…• ,

์•„์ง ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค(๋˜๋Š” ๋‚ด๊ฐ€ ๋†“์น˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๊นŒ). ์–ธ์ œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ๋ ค์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์—ฌ๊ถŒ ๊ฐฑ์‹  ํ† ํฐ ์ €์žฅ์†Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ฌด๋„ ์ด๊ฒƒ์„ ์‹œ๋„ ํ–ˆ์Šต๋‹ˆ๊นŒ?
https://github.com/fiznool/passport-oauth2-refresh

์•ˆ๋…•ํ•˜์„ธ์š” @daffl๋‹˜
Google ์ „๋žต์„ ์œ„ํ•ด ํ† ํฐ์„ ์ƒˆ๋กœ ๊ณ ์น  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ดํ•ดํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ค„ ์ˆ˜ ์žˆ๋Š” ์‚ฌ๋žŒ์ด ์žˆ์Šต๋‹ˆ๊นŒ? Google ๋กœ๊ทธ์ธ ์‹œ๋‚˜๋ฆฌ์˜ค์— ๋Œ€ํ•œ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์—?

๊ฐ์‚ฌ ํ•ด์š”

๋˜ ๋‹ค๋ฅธ ์ ‘๊ทผ ๋ฐฉ์‹์€ accessToken์˜ ํŽ˜์ด๋กœ๋“œ ๋‚ด๋ถ€์— ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ์ €์žฅํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋งŒ๋ฃŒ๋œ ์•ก์„ธ์Šค ํ† ํฐ ์ค‘ ํ•˜๋‚˜ ๋ผ๋„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์‚ฌ๋žŒ์€ ๋ˆ„๊ตฌ๋‚˜ ์‰ฝ๊ฒŒ ์ƒˆ๋กœ์šด ์•ก์„ธ์Šค ํ† ํฐ์„ ๋์—†์ด ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋‹ˆ๋ฉด ์ œ๊ฐ€ ๋†“์นœ ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์€ ํด๋ผ์ด์–ธํŠธ์— ์•ˆ์ „ํ•˜๊ฒŒ ์ €์žฅ๋˜์–ด์•ผ ํ•˜๋ฉฐ ์ด ํด๋ผ์ด์–ธํŠธ๋ฅผ ์ œ์™ธํ•œ ๋ˆ„๊ตฌ๋„ ํ† ํฐ์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์—†์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค!

@deiucanta ์ข‹์€ ์†Œ์‹์€ [email protected] ์„ ์„ค๊ณ„ํ•˜๋Š” ๋™์•ˆ ์ด ๊ธฐ๋Šฅ์„ ์—ผ๋‘์—

์ด๊ฒƒ์€ 2016๋…„์— ๊ฒŒ์‹œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ๋ถ„, ์ด ํ•„์ˆ˜ ๊ธฐ๋Šฅ์„ ์•„์ง ์ง€์›ํ•  ๊ณ„ํš์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์•„๋‹ˆ์š”. ๋งŒ๋ฃŒ๋œ ํ† ํฐ์œผ๋กœ๋Š” ์•„๋ฌด ๊ฒƒ๋„ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๊ฐฑ์‹  ํ† ํฐ์€ v4 ์‹œํ—˜ํŒ ์—์„œ ํ›จ์”ฌ ๋” ์‰ฝ๊ฒŒ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์š”๋ฆฌ์ฑ… ํ•ญ๋ชฉ์€ ์ตœ์ข… ๋ฆด๋ฆฌ์Šค์˜ ์ผ๋ถ€๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ ๊ฐฑ์‹  ํ† ํฐ์€ v4 ์‹œํ—˜ํŒ ์—์„œ ํ›จ์”ฌ ๋” ์‰ฝ๊ฒŒ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๋Œ€๋žต์ ์ธ ์ถœ์‹œ์ผ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๊ทธ๊ฒƒ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์š”๋ฆฌ์ฑ… ํ•ญ๋ชฉ์€ ์ตœ์ข… ๋ฆด๋ฆฌ์Šค์˜ ์ผ๋ถ€๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด ๊ฐ€์ด๋“œ๊ฐ€ ์ถœ์‹œ๋  ๋•Œ๊นŒ์ง€ v4 ํ”„๋ฆฌ๋ฆด๋ฆฌ์ฆˆ์—์„œ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ๋ช‡ ๋งˆ๋””๋กœ ์„ค๋ช…ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

@๋Œ€ํ”Œํ•‘

์•„์ง ๊ณต์‹์ ์ธ ๋ฐฉ๋ฒ•์ด ์—†๋‚˜์š”? v4๊ฐ€ ์—ฌ๊ธฐ์— ์žˆ์œผ๋ฉฐ ๋ฌธ์„œ์— ์•„๋ฌด ๊ฒƒ๋„ ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@daffl ์ธ์ฆ ์„œ๋น„์Šค์— ๋Œ€ํ•œ ํ•ดํ‚น ์—†์ด 4.0์—์„œ ์ด๊ฒƒ์ด ์–ด๋–ป๊ฒŒ ๋‹ฌ์„ฑ๋  ์ˆ˜ ์žˆ๋Š”์ง€ ์ž์„ธํžˆ ์„ค๋ช…ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

@MichaelErmer ๋ฅผ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์œผ๋กœ ๋กœ์ปฌ ๋˜๋Š” ์‚ฌ์šฉ์ž ์ •์˜ ์ „๋žต์„ ์‚ฌ์šฉํ•˜์—ฌ jwt๋ฅผ ๊ฐฑ์‹ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด์ƒ์ ์ด์ง€๋Š” ์•Š์ง€๋งŒ ๋‚ด๋ถ€ ํ†ต์‹ ์—๋Š” ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

function initAuth() {
  return async (ctx) => {
    if (ctx.path !== 'authentication') {
      const [authenticated, accessToken] = await Promise.all([
        ctx.app.get('authentication'),
        ctx.app.authentication.getAccessToken(),
      ]);

      if (!accessToken || !authenticated) {
        const result = await ctx.app.authenticate(apiLocalCreds);
        ctx.params = {
          ...ctx.params,
          ...result,
          headers: { ...(ctx.params.headers || {}), Authorization: result.accessToken },
        };
      } else {
        const { exp } = decode(accessToken);
        const expired = Date.now() / 1000 > exp - 60 * 60;
        if (expired) {
          const result = await ctx.app.authenticate(apiLocalCreds);
          ctx.params = {
            ...ctx.params,
            ...result,
            headers: { ...(ctx.params.headers || {}), Authorization: result.accessToken },
          };
        }
      }
    }
    return ctx;
  };
}

client
  .configure(rest(apiHost).superagent(superagent))
  .configure(auth(authConfig))
  .hooks({ before: [initAuth()] });

ํ˜„์žฌ ์ €๋Š” v4 authentication ์—์„œ ์ด after ํ›„ํฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ 20์ผ ํ›„์— ๋‚ด accessToken์„ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค...

````์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ
const {๋‚ ์งœ ์‹œ๊ฐ„} = ์š”๊ตฌ('luxon')
const ๊ฐฑ์‹  ํ›„ = {์ผ: 20}

module.exports = () => {
๋น„๋™๊ธฐ ์ปจํ…์ŠคํŠธ ๋ฐ˜ํ™˜ => {
๋งŒ์•ฝ (
context.method === '๋งŒ๋“ค๊ธฐ' &&
context.type === '๋’ค์—' &&
context.path === '์ธ์ฆ' &&
context.data && context.data.strategy === 'jwt' &&
context.result &&
context.result.accessToken) {
// ํ† ํฐ ๊ฐฑ์‹ ์ด ํ•„์š”ํ•œ์ง€ ํ™•์ธ
const ํŽ˜์ด๋กœ๋“œ = context.app.service('์ธ์ฆ').verifyAccessToken(context.result.accessToken)์„ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค.
const ๋ฐœํ–‰ ์‹œ๊ฐ„ = DateTime.fromMillis(payload.iat * 1000)
const ๊ฐฑ์‹ ํ›„ = ๋ฐœํ–‰๋œAt.plus(๊ฐฑ์‹ ํ›„)
์ง€๊ธˆ const = DateTime.local()
if (์ง€๊ธˆ > ๊ฐฑ์‹ ํ›„) {
context.result.accessToken = ๋Œ€๊ธฐ context.app.service('์ธ์ฆ').createAccessToken({sub: payload.sub})
}
}
์ปจํ…์ŠคํŠธ ๋ฐ˜ํ™˜
}
}
````

์ด ํ›„ํฌ๋ฅผ after ๋ฐ ๋งˆ์ง€๋ง‰ ํ›„ํฌ๋กœ ๋‘์–ด ๋ชจ๋“  ํ™•์ธ ๋“ฑ์ด ํ†ต๊ณผ๋˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

๊นƒํ„ธ์— ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ํ†ตํ•ฉํ•  ๊ณ„ํš์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๋‚˜๋Š” ๊ทธ ์งˆ๋ฌธ์„ ํ•œ ๋ฉ”์‹œ์ง€ ๋” ์ผ์ฐ ๋‘ ๋ฒˆ์งธ๋กœ ํ•œ๋‹ค.

์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ ์›Œํฌํ”Œ๋กœ์— ๋Œ€ํ•ด์„œ๋„ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค. @m0dch3n ์ด ์ž‘์„ฑํ•œ ์†”๋ฃจ์…˜์ด ์ข‹์€ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๊นŒ? ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์œผ๋กœ ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

๋‚ด ์˜๊ฒฌ์˜ ์ „์ฒด refreshToken ์›Œํฌํ”Œ๋กœ๋Š” ์ค‘๊ฐ„ ๊ณต๊ฒฉ์ž์— ๋Œ€ํ•ด ์•ฝ๊ฐ„๋งŒ ๋ณดํ˜ธํ•˜๋ฏ€๋กœ ์ค‘๊ฐ„ ์‚ฌ๋žŒ์ด accessToken์„ ํ›”์นœ๋‹ค๋ฉด ์ตœ์†Œํ•œ ์ƒˆ๋กœ ๊ณ ์นจํ•  ์ˆ˜ ์—†๊ณ  ๋ฆฌ์†Œ์Šค์— ๋ฌดํ•œํ•œ ์•ก์„ธ์Šค ๊ถŒํ•œ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

์ด์ œ ๋ฌธ์ œ๋Š” accessToken ๋งŒ๋ฃŒ ์‹œ๊ฐ„์„ ๋„ˆ๋ฌด ์งง๊ฒŒ(์ฆ‰, 5๋ถ„) ๋งŒ๋“ค๋ฉด ๋„ˆ๋ฌด ์ž์ฃผ ์ƒˆ๋กœ ๊ณ ์นจ์„ ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ค‘๊ฐ„์— ์žˆ๋Š” ๋‚จ์ž๋Š” refreshToken์„ ๊ฐ€๋กœ์ฑ„๊ธฐ ์œ„ํ•ด ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ์„ 5๋ถ„ ๋™์•ˆ๋งŒ ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด... ๋งŒ๋ฃŒ๋ฅผ ๋” ๊ธธ๊ฒŒ ๋งŒ๋“ค๋ฉด accessToken๋งŒ์œผ๋กœ๋„ ๋” ์˜ค๋ž˜ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค...

์†”์งํžˆ ์ผ๋ถ€ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์•ก์„ธ์Šค ๊ถŒํ•œ์„ ๋„๋‚œ๋‹นํ–ˆ๋‹ค๊ณ  ๋งํ•˜๋ฉด accessToken ๊ณผ refreshToken์„ ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€ํ•ด์•ผ ํ™•์‹คํ•˜๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์–ด์จŒ๋“  ๊ฐ ์š”์ฒญ์— ๋Œ€ํ•ด DB ์š”์ฒญ์„ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์ œ ๊ฒฝ์šฐ์—๋Š” ๊ทธ๋Ÿฌํ•œ ๊ฒฝ์šฐ๋ฅผ ์•Œ๊ณ  ์žˆ์„ ๋•Œ ์ง€๋‚œ 40์ผ ๋™์•ˆ์˜ ๋ชจ๋“  accessTokens๋ฅผ ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ์— ์˜ฌ๋ ธ์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์ œ accessTokens์˜ ์œ ํšจ ๊ธฐ๊ฐ„์ด 40์ผ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค...

HTTPS ์š”์ฒญ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ค‘๊ฐ„์ž ๊ณต๊ฒฉ์ด ์ •๋ง ์–ด๋ ค์›Œ์ง‘๋‹ˆ๋‹ค. HTTPS ์š”์ฒญ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์ง€ ์•Š์Šต๋‹ˆ๊นŒ?

๋ฌผ๋ก  ์ €๋Š” https๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์ง€๋งŒ accessToken์„ ํ›”์น  ๊ฐ€๋Šฅ์„ฑ์€ 3๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ๋Š” ํด๋ผ์ด์–ธํŠธ ์ธก(์˜ˆ: XSS), ๋‘ ๋ฒˆ์งธ๋Š” ์ „์†ก(๊ฐ€์šด๋ฐ ์‚ฌ๋žŒ), ์„ธ ๋ฒˆ์งธ๋Š” ์„œ๋ฒ„ ์ธก์ž…๋‹ˆ๋‹ค.

ํด๋ผ์ด์–ธํŠธ์™€ ์ „์†ก์—์„œ ๋‚˜๋Š” ๋ณด์•ˆ์— ๋Œ€ํ•œ ์ ˆ๋ฐ˜๋งŒ ์ฑ…์ž„์ง€๊ณ  ๋‚˜๋จธ์ง€ ์ ˆ๋ฐ˜์€ ๋‚ด ํ†ต์ œ ํ•˜์— ์žˆ์ง€ ์•Š์€ ํด๋ผ์ด์–ธํŠธ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ XSS๋ฅผ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ค๊ณ  https๋กœ ์ „์†ก์„ ๋ณดํ˜ธํ•จ์œผ๋กœ์จ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ณด์•ˆ ์œ„ํ—˜์„ ํ”ผํ•˜๋„๋ก ๋„์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

refreshToken์˜ ๋ชฉํ‘œ๋Š” accessToken์˜ ๋งŒ๋ฃŒ๋ฅผ ๋” ์งง๊ฒŒ ๋งŒ๋“ค๊ณ  ๊ฐ ์š”์ฒญ์— ๋Œ€ํ•ด ๋” ๊ธธ๊ฑฐ๋‚˜ ๋ฌดํ•œํ•œ ์œ ํšจํ•œ ํ† ํฐ์„ ์ „์†กํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์ด๊ฒƒ์ด ์ œ๊ณตํ•˜๋Š” ์œ ์ผํ•œ ๋ณด์•ˆ์€ 100๊ฐœ์˜ ์š”์ฒญ์—์„œ ์ฆ‰, ์ „์†ก ์‹œ 100๊ฐœ ๋ชจ๋‘๋ฅผ ์ทจ์•ฝํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ 1๊ฐœ์˜ ์š”์ฒญ๋งŒ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ค‘๊ฐ„ ๊ณต๊ฒฉ์ž๋Š” refeshToken์— ์˜ํ•ด ๋ณดํ˜ธ๋  ์ˆ˜ ์—†์œผ๋ฉฐ ๋ฌผ๋ก  XSS์— ์˜ํ•ด ๋ณดํ˜ธ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค... ์ด refreshToken์„ ์ „์†กํ•˜๋Š” ํšŸ์ˆ˜๋งŒํผ ์ค„์ผ ์ˆ˜ ์žˆ์„ ๋ฟ์ž…๋‹ˆ๋‹ค... ์ „์†ก ๋น„์šฉ์€ ๋” ์ ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ accessToken์€ ๋” ์˜ค๋ž˜ ์œ ํšจํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค...

Slack ์ฑ„๋„์—์„œ ๋‚ด ๋Œ“๊ธ€์„ ๋ณต์‚ฌ/๋ถ™์—ฌ๋„ฃ๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์ƒˆ๋กœ๊ณ ์นจ ํ† ํฐ์€ ํ•„์ˆ˜ ์ง€์› ๊ธฐ๋Šฅ์ด๋ฉฐ ๊ธฐ์กด ์•ก์„ธ์Šค ํ† ํฐ์„ ์ž๋™์œผ๋กœ ๊ฐฑ์‹ ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์•ก์„ธ์Šค ํ† ํฐ์€ ์ƒํƒœ ๋น„์ €์žฅ์ด๋ฉฐ ์„œ๋ฒ„ ์ธก์— ์ €์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹จ์ ์€ ์˜์›ํžˆ ์œ ํšจํ•˜๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค! ์•ก์„ธ์Šค ํ† ํฐ์ด ๊ธธ์ˆ˜๋ก ๋” ๋งŽ์€ ์œ„ํ—˜์ด ๋ถ€๊ณผ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์•ก์„ธ์Šค ํ† ํฐ์ด ๋„ˆ๋ฌด ์งง์œผ๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์ž์ฃผ ๋กœ๊ทธ์ธํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์‚ฌ์šฉ์„ฑ์— ํฐ ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค.

๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ์ด ๋“ค์–ด์˜ค๋Š” ๊ณณ์ž…๋‹ˆ๋‹ค. ์•ก์„ธ์Šค ํ† ํฐ์„ ์ƒˆ๋กœ ๊ณ ์น˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ํ† ํฐ์ด๋ฉฐ ์ˆ˜๋ช…์ด ๊ธด ํ† ํฐ์ž…๋‹ˆ๋‹ค. ์•ก์„ธ์Šค ํ† ํฐ์ด ๋งŒ๋ฃŒ๋˜๋ฉด ํด๋ผ์ด์–ธํŠธ๋Š” ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ ์•ก์„ธ์Šค ํ† ํฐ์„ ์–ป์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ด๊ฒƒ์ด ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์˜ ์œ ์ผํ•œ ๋ชฉ์ ์ž…๋‹ˆ๋‹ค.

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

์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ตฌํ˜„ํ•˜๋ ค๋ฉด ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์ผ์ข…์˜ ํ† ํฐ ์ €์žฅ์†Œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์ตœ์†Œํ•œ ์„ธ ๊ฐ€์ง€ ํ๋ฆ„์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํ† ํฐ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์ƒˆ๋กœ ๊ณ ์นจ
์œ ํšจํ•œ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์œผ๋กœ ์•ก์„ธ์Šค ํ† ํฐ ์ƒˆ๋กœ ๊ณ ์นจ
์†์ƒ๋œ ์‚ฌ์šฉ์ž์˜ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ ์ทจ์†Œ

ํ† ํฐ ์‚ฌ์šฉ ํ†ต๊ณ„์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ๊ด€๋ฆฌ ๊ธฐ๋Šฅ๋„ ์žˆ์œผ๋ฉด ์ข‹์Šต๋‹ˆ๋‹ค.

์œ„๋Š” ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ํ˜„์žฌ ์ดํ•ด์ž…๋‹ˆ๋‹ค. ์‰ฝ์ง€๋Š” ์•Š์ง€๋งŒ ๋ณด๋‹ค ์•ˆ์ „ํ•œ ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒƒ์€ ๋ฐ˜๋“œ์‹œ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๋ชจ๋“  ๊ธฐ๋Šฅ/๋ชจ๋“ˆ์ด Feathers์— ์ด๋ฏธ ๋‚ด์žฅ๋˜์–ด ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ๋‚˜ํƒ€๋‚ฌ์Šต๋‹ˆ๋‹ค.

  1. Refresh-token store: Feathers Service์—์„œ ์‰ฝ๊ฒŒ ์ง€์›๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  2. ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ ๋ฐœ๊ธ‰ ๋ฐ ๊ฒ€์ฆ: ๋‚ด์žฅ๋œ AuthenticationService๊ฐ€ ์ง€์›ํ•˜๋Š” ๊ธฐ์กด JWT๋ฅผ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

TheSinding(https://github.com/TheSinding/authentication-refresh-token)์ด ์ˆ˜ํ–‰ํ•œ ์ž‘์—…์„ ๊ธฐ๋ฐ˜์œผ๋กœ, ํ•˜๋‚˜์˜ ์‚ฌ์šฉ์ž ์ง€์ • ์„œ๋น„์Šค์™€ ์„ธ ๊ฐœ์˜ ํ›„ํฌ(https://github.com/ ๊ธฐ๋ณธ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ ๊ธฐ๋Šฅ์„ ํ™œ์„ฑํ™”ํ•˜๋Š” jackywxd/feathers-refresh-token):

  1. ์‚ฌ์šฉ์ž ์ธ์ฆ์— ์„ฑ๊ณตํ•œ ํ›„ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ๋ฐœํ–‰ํ•˜์‹ญ์‹œ์˜ค.
  2. ์œ ํšจํ•œ JWT ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์œผ๋กœ ์•ก์„ธ์Šค ํ† ํฐ์„ ์ƒˆ๋กœ ๊ณ ์นฉ๋‹ˆ๋‹ค.
  3. ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ์‚ญ์ œํ•˜์—ฌ ์‚ฌ์šฉ์ž ๋กœ๊ทธ์•„์›ƒ

Feathres์˜ ๊ธฐ์กด ์ฝ”๋“œ ๊ธฐ๋ฐ˜์„ ์ตœ๋Œ€ํ•œ ํ™œ์šฉํ•˜๋ฉด์„œ ์‹ค์ œ ์ฝ”๋”ฉ ๋…ธ๋ ฅ์€ ์ตœ์†Œํ™”๋˜์—ˆ์œผ๋ฉฐ ํ˜„์žฌ Feathers ์•„ํ‚คํ…์ฒ˜์™€ ์ž˜ ํ†ตํ•ฉ๋ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ Feathers ์•„ํ‚คํ…์ฒ˜๊ฐ€ ๋งค์šฐ ํ™•์žฅ ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์ฆ๋ช…ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ Refresh-token์˜ ์ „์ฒด ๊ธฐ๋Šฅ์€ ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ ์ €์žฅ, ์•ก์„ธ์Šค ํ† ํฐ ๋งŒ๋ฃŒ ํ›„ ์‚ฌ์šฉ์ž ์žฌ์ธ์ฆ, ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์œผ๋กœ ์‚ฌ์šฉ์ž ๋กœ๊ทธ์•„์›ƒ๊ณผ ๊ฐ™์€ ํด๋ผ์ด์–ธํŠธ ์ธก ์ง€์›๋„ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

feather-authentication ๋ฐ authentication-client์˜ ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ๊ฒ€ํ† ํ•œ ํ›„ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ์ธ์ฆ์„ ์ผœ๋Š” ๊ฒƒ๋งŒํผ ์‰ฝ๊ฒŒ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ ์ง€์›์„ ์ผค ์ˆ˜ ์žˆ๋„๋ก ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ๊ธฐ์กด ๊ธฐ๋Šฅ ์ฝ”๋“œ์— ํƒญํ•‘ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

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

๋‚ด ์งˆ๋ฌธ/๊ด€์‹ฌ์€ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์ด ํด๋ผ์ด์–ธํŠธ์— ์–ด๋–ป๊ฒŒ ์ €์žฅ๋ฉ๋‹ˆ๊นŒ?

https://auth0.com/blog/securing-single-page-applications-with-refresh-token-rotation/ ์ฐธ์กฐ

๋ถˆํ–‰ํžˆ๋„ ์ˆ˜๋ช…์ด ๊ธด RT๋Š” SPA์— ์ ํ•ฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์—๋Š” ์˜๋„ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋งŒ ์•ก์„ธ์Šค๋ฅผ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ๋Š” ์˜๊ตฌ ์ €์žฅ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ณ ๊ฐ€์น˜ ์•„ํ‹ฐํŒฉํŠธ๋ฅผ ํš๋“ํ•˜๊ณ  ์•…์˜์ ์ธ ํ–‰์œ„์ž๊ฐ€ ๋ณดํ˜ธ๋œ ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ์•ก์„ธ์Šค ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๊ธฐ ์œ„ํ•ด ์•…์šฉ๋  ์ˆ˜ ์žˆ๋Š” ์ทจ์•ฝ์ ์ด ์žˆ์œผ๋ฏ€๋กœ SPA์—์„œ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๊ฐ•๋ ฅํžˆ ๊ถŒ์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

https://afteracademy.com/blog/implement-json-web-token-jwt-authentication-using-access-token-and-refresh-token ์ฐธ์กฐ

๊ทธ๋ ‡๋‹ค๋ฉด ํ† ํฐ์„ ์•ˆ์ „ํ•˜๊ฒŒ ๋ณด๊ด€ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ์ข‹์€ ์žฅ์†Œ๋Š” ์–ด๋””์ผ๊นŒ์š”? ์™„์ „ํžˆ ์•ˆ์ „ํ•œ ์Šคํ† ๋ฆฌ์ง€๋ฅผ ํ™•๋ณดํ•˜๋ ค๋Š” ์—ด์ •์ด ์žˆ๋‹ค๋ฉด ์ธํ„ฐ๋„ท์—์„œ ์ด์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์„ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ถ€ ์†”๋ฃจ์…˜์€ ์ด์ƒ์ ์ด์ง€๋งŒ ๊ทธ๋‹ค์ง€ ์‹ค์šฉ์ ์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ httpOnly ๋ฐ Secure ํ”Œ๋ž˜๊ทธ๊ฐ€ ์žˆ๋Š” ์ฟ ํ‚ค์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. 100% ์•ˆ์ „ํ•˜์ง€๋Š” ์•Š์ง€๋งŒ ์ž‘์—…์„ ์™„๋ฃŒํ•ฉ๋‹ˆ๋‹ค.

์ฟ ํ‚ค์— ๋Œ€ํ•œ ์ด ๊ธด ํ† ๋ก ์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค - https://github.com/feathersjs-ecosystem/authentication/issues/132 too

@bwgjoseph ์ผ๋ฐ˜ ์ต์Šคํ”„๋ ˆ์Šค ์„ธ์…˜์„ ์‚ฌ์šฉํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ ์ธก ๋Œ€์‹  ๋ชจ๋“  ํ† ํฐ์„ ๊ฑฐ๊ธฐ์— ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ด ๋‚ด๊ฐ€ํ•˜๋Š” ์ผ์ด๋ฉฐ SPA๋ฅผ ํฌํ•จํ•œ ๋ชจ๋“  ์œ ํ˜•์˜ ์•ฑ์—์„œ ์™„๋ฒฝํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

@sarkistlt ๋ชจ๋“  ํด๋ผ์ด์–ธํŠธ JWT ํ† ํฐ์„ ์„œ๋ฒ„ ์ธก์— ์ €์žฅํ•œ๋‹ค๋Š”

@bwgjoseph ์–ธ์ œ๋‚˜์ฒ˜๋Ÿผ ์ฟ ํ‚ค, ์„œ๋น„์Šค๋ฅผ ๋“ฑ๋กํ•˜๊ธฐ ์ „์—

app.use('* | [or specific rout]', session(sess), (req, res, next) => {
      req.feathers.session = req.session || {};
      next();
    });

๊ทธ๋Ÿฐ ๋‹ค์Œ ์„œ๋ฒ„์—์„œ ๊ณ ๊ฐ ๋กœ๊ทธ์ธ ์„œ๋น„์Šค์˜ ๊ฒฝ์šฐ ๊ณ ๊ฐ์ด ์ธ์ฆ๋˜๋ฉด ctx.params.session.token = token ์™€ ๊ฐ™์€ ์„ธ์…˜์— ํ† ํฐ์„ ์ €์žฅํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ํ† ํฐ์€ JWT ์•ก์„ธ์Šค ๋˜๋Š” ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์ด๋ฉฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋…ผ๋ฆฌ์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ํด๋ผ์ด์–ธํŠธ์˜ ์ƒˆ๋กœ์šด ์š”์ฒญ์ด ์žˆ์œผ๋ฉด ์„ธ์…˜์— ํ† ํฐ์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ์ด๋ฅผ ์ธ์ฆ์— ์‚ฌ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ ํ† ํฐ์ด ์ „ํ˜€ ๋…ธ์ถœ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์€ ํ›จ์”ฌ ๋” ์•ˆ์ „ํ•˜๊ณ  ์•ˆ์ „ํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์ด ํด๋ผ์ด์–ธํŠธ(๋ธŒ๋ผ์šฐ์ €) - ์„œ๋ฒ„ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์— ๊ฐ€์žฅ ์ž˜ ์ž‘๋™ํ•œ๋‹ค๊ณ  ๋ง๋ถ™์ด๊ฒ ์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„ ๋˜๋Š” ์ž‘์—…์ž/์„œ๋ฒ„ ๊ฐ„์— ๋‚ด๋ถ€์ ์œผ๋กœ ํ†ต์‹ ํ•  ๋•Œ๋Š” ์„ธ์…˜์ด ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์ด์ „์— _๋งŽ์ด_ ๋…ผ์˜๋˜์—ˆ์œผ๋ฉฐ(๋˜ํ•œ FAQ์— ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค) ์„ธ์…˜์— ํ† ํฐ์„ ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด ๋ฐ˜๋“œ์‹œ ๋” ์•ˆ์ „ํ•œ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํŽ˜์ด์ง€์— ์•ก์„ธ์Šคํ•˜๋ฉด ์„ธ์…˜์„ ๊ฐ€๋กœ์ฑ„๊ณ  ์–ด์จŒ๋“  ์ธ์ฆ๋œ ์š”์ฒญ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์ผ๋ฐ˜์ ์œผ๋กœ ํ† ํฐ์„ ์˜ˆ๋ฅผ ๋“ค์–ด localStorage(ํ˜„์žฌ ํŽ˜์ด์ง€์—๋งŒ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Œ)์— ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด ์ข‹์œผ๋ฉฐ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ํ”Œ๋žซํผ(๋„ค์ดํ‹ฐ๋ธŒ ๋ชจ๋ฐ”์ผ ์•ฑ, ์„œ๋ฒ„ ๊ฐ„ ๋“ฑ)๊ณผ๋„ ์›ํ™œํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. websockets__ (์›น ์†Œ์ผ“์ด HTTP ์ฟ ํ‚ค๋กœ ์›ํ™œํ•˜๊ณ  ์•ˆ์ „ํ•˜๊ฒŒ ์ž‘๋™ํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ์–ผ๋งˆ๋‚˜ ๊ณ ํ†ต์Šค๋Ÿฌ์šด์ง€ ์ถฉ๋ถ„ํžˆ ๊ฐ•์กฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ๊ทธ๋ ‡๊ฒŒ ํ•˜๋ ค๊ณ  ํ•˜์ง€ ์•Š์€ ์ดํ›„๋กœ ์ œ ์‚ถ์€ ํ›จ์”ฌ ์‰ฌ์›Œ์กŒ์Šต๋‹ˆ๋‹ค). ์ผ๋ฐ˜์ ์œผ๋กœ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์€ ์ˆ˜๋ช…์ด ํ›จ์”ฌ ๋” ๊ธธ๊ธฐ ๋•Œ๋ฌธ์— ์ทจ์†Œํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์–ด๋Š ์ชฝ์ด๋“ , ์ด๊ฒƒ์— ๋Œ€ํ•œ ํ’€ ๋ฆฌํ€˜์ŠคํŠธ๋Š” ๋งค์šฐ ํ™˜์˜๋ฐ›์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ํ›จ์”ฌ ์‰ฝ๊ฒŒ ๋‹ค๋ฆผ์งˆํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@jackywxd - ํ›Œ๋ฅญํ•œ ์ž‘์—…์ž…๋‹ˆ๋‹ค. ๊ฐ„๋‹จํžˆ ์‚ดํŽด๋ณด์•˜๊ณ  ๋ช‡ ๊ฐ€์ง€ ํ›Œ๋ฅญํ•œ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์ด ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
์–ด์จŒ๋“  ๊ฐœ๋ฐœ์ž๊ฐ€ ์ด๊ฒƒ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?
๋งŒ๋“  ํ›„ํฌ๋ฅผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ํ†ตํ•ฉํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋‚˜์ค‘์— ํ›„ํฌ๋ฅผ ์ถ”๊ฐ€ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๊นŒ?

ํ’€ ๋ฆฌํ€˜์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๊ฑฐ๊ธฐ์—์„œ ํ† ๋ก ์„ ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@daffl ์˜ˆ, ํŠนํžˆ WS์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํด๋ผ์ด์–ธํŠธ์™€ ๋ฐฑ์—”๋“œ๊ฐ€ ๋ชจ๋‘ ๊ท€ํ•˜ ๋˜๋Š” ๊ท€ํ•˜์˜ ํŒ€์— ์˜ํ•ด ๊ตฌ์ถ•๋˜๋Š” ๊ฒฝ์šฐ JWT๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ถ”๊ฐ€ ์ข…์†์„ฑ๊ณผ ๋ณต์žก์„ฑ์„ ํ”ผํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ์–ด๋–ค ๊ฒฝ์šฐ์—๋Š” ์˜ˆ๋ฅผ ๋“ค์–ด ํƒ€์‚ฌ ํšŒ์‚ฌ/๊ฐœ๋ฐœ์ž๊ฐ€ ์‚ฌ์šฉํ•  ์ƒ์  ์•ž REST-API๋ฅผ ๊ตฌ์ถ•ํ•  ๋•Œ ์ผ๋ฐ˜ ์„ธ์…˜์„ ์‚ฌ์šฉํ•˜๊ณ  ๊ฐœ๋ฐœ์ž์—๊ฒŒ ์š”์ฒญ์— ์ž๊ฒฉ ์ฆ๋ช…์„ ํฌํ•จํ•˜๋„๋ก ์š”์ฒญํ•œ ๋‹ค์Œ ์•ก์„ธ์Šค(๋ฐ ์ƒˆ๋กœ ๊ณ ์นจ) ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•˜๋„๋ก ์š”์ฒญํ•˜๋Š” ๊ฒƒ์ด ๋” ์‰ฝ์Šต๋‹ˆ๋‹ค. ) ํ† ํฐ์„ ์ €์žฅํ•˜๊ณ  ๊ฐ ์š”์ฒญ๊ณผ ํ•จ๊ป˜ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ํŽ˜๋” ํด๋ผ์ด์–ธํŠธ์—์„œ ์™„๋ฒฝํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜์ง€๋งŒ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ฐฑ์—”๋“œ ๋นŒ๋“œ ๋ฐฉ๋ฒ•์— ์ต์ˆ™ํ•˜์ง€ ์•Š์€ ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ request, superagent, fetch or axios ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฐฑ์—”๋“œ์— ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ์ ์–ด๋„ ์ œ ๊ฒฝ์šฐ์—๋Š” ์ด๊ฒƒ์ด JWT๊ฐ€ ์•„๋‹Œ ์ผ๋ฐ˜ ์„ธ์…˜์—์„œ ์ง์ ‘ ์ž‘๋™ํ•˜๋„๋ก API์˜ ์ฒซ ํ™”๋ฉด ๋ถ€๋ถ„์„ ์ด๋™ํ•˜๋Š” ์ฃผ๋œ ์ด์œ ์˜€์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ด ๊ฒฐ์ •์„ ์ปค๋ฎค๋‹ˆํ‹ฐ์— "๊ฐ•์ œ"ํ•˜๋Š” ๋Œ€์‹  ์ž์ฒด API๋กœ ๊ตฌํ˜„ํ•œ ๋‹ค์Œ ์ด ๊ธฐ๋Šฅ์„ ์ ์ ˆํ•˜๊ฒŒ ๋ฌธ์„œํ™”ํ•˜๋Š” ๊ฒƒ์ด ๋””์ž์ธ ๊ฒฐ์ •๊ณผ ์ฑ…์ž„์ด ํ•ด๋‹น ์ƒ์ ์˜ ์ œ์ž‘์ž์—๊ฒŒ ์žˆ์ง€ ์•Š์„๊นŒ์š”?

@TheSinding ์‚ฌ์šฉ์ž ์„ธ์…˜์„ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์ ‘๊ทผ ๋ฐฉ์‹์ธ ์ฟ ํ‚ค๊ฐ€ ์•„๋‹ˆ๋ผ ๋œ ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์ ‘๊ทผ ๋ฐฉ์‹์— ๋Œ€ํ•ด '๊ฐ•์ œ'๋ผ๊ณ  ๋งํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

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

๋‹ค์‹œ ๋งํ•˜์ง€๋งŒ JWT๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ํ›Œ๋ฅญํ•˜๊ณ  ํŠนํžˆ ์‹ค์‹œ๊ฐ„ API์— ํ™œ์šฉํ•˜๊ธฐ๊ฐ€ ํ›จ์”ฌ ๋” ์‰ฝ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ 90%์˜ ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. + ์ฟ ํ‚ค ์„ธ์…˜์„ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด redis ๋˜๋Š” ๋‹ค๋ฅธ ๊ฒƒ์„ ์‹คํ–‰ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ์ตœ์„ ์˜ ์„ ํƒ์ด ์•„๋‹ ์ˆ˜ ์žˆ๋Š” ์˜ˆ์™ธ์ ์ธ ๊ฒฝ์šฐ๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ ์ด์ „ ์˜๊ฒฌ์—์„œ ํ•ด๋‹น ์ƒํ™ฉ์˜ ์˜ˆ๋ฅผ ๊ฐ€์ ธ์™”์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋‹น์‹ ์ด ํ‹€๋ ธ๋‹ค๊ณ  ๋งํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ "ํฐ ์†Œ๋ฆฌ๋กœ"์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค :)

IMO, JWT๋ฅผ ์‚ฌ์šฉํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์ด ๋” ๋‚˜์€ ์ ‘๊ทผ ๋ฐฉ์‹์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฏธ ์ง€์›๋˜๊ณ  @daffl ๋กœ ์ž‘์—…ํ•˜๊ธฐ๋„ ๋” ์‰ฝ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๋ชจ๋“  ํ”ผ๋“œ๋ฐฑ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค! JWT ๋Œ€ ์„ธ์…˜์€ ๋ณ„๋„๋กœ ๋…ผ์˜ํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค๋ฅธ ์ฃผ์ œ์ž…๋‹ˆ๋‹ค.

์šฐ๋ฆฌ ๋ชจ๋‘๊ฐ€ ๋™์˜ํ•˜๋Š” ํ•œ ๊ฐ€์ง€๋Š” ์•ก์„ธ์Šค ํ† ํฐ + ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์ด ๋‹จ์ˆœํ•œ ์•ก์„ธ์Šค ํ† ํฐ๋ณด๋‹ค ํ›จ์”ฌ ๋” ์•ˆ์ „ํ•œ ์†”๋ฃจ์…˜์ด๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ์ฃผ์š” ์ธํ„ฐ๋„ท ๊ฑฐ์ธ์— ์˜ํ•ด ๋„๋ฆฌ ์ฑ„ํƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. Feathers ์ปค๋ฎค๋‹ˆํ‹ฐ๋Š” ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์— ๋Œ€ํ•œ ๊ธฐ๋ณธ ์ œ๊ณต ์ง€์›์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด Feathers ๊ธฐ๋ณธ ์ฝ”๋“œ ๊ธฐ๋ฐ˜์„ ๋ณด๊ณ  ์‹ถ์–ดํ•œ๋‹ค๊ณ  ๋งํ•˜๋Š” ๊ฒƒ์ด ํƒ€๋‹นํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์‹ค Feathers๊ฐ€ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์‚ฌ์‹ค์„ ์ฒ˜์Œ ์•Œ์•˜์„ ๋•Œ ๋†€๋ž์Šต๋‹ˆ๋‹ค.

์ €๋Š” ๋ช‡ ๊ฐ€์ง€ ํ”„๋กœ์ ํŠธ์—์„œ AWS cognito๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. AWS Amplify๋Š” ID ํ† ํฐ, ์•ก์„ธ์Šค ํ† ํฐ ๋ฐ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ๊ณผ ๊ฐ™์€ ์„ธ ๊ฐ€์ง€ ํ† ํฐ์„ localStorage์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. Amplify๋Š” ํ† ํฐ ๊ด€๋ฆฌ์™€ ๊ด€๋ จ๋œ ๋ชจ๋“  ๋”๋Ÿฌ์šด ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ์‰ฝ๊ณ  ๊ฐ„ํŽธํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ API๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. Cognito ๋ฐฑ์—”๋“œ์™€ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋Š” ์ง๊ด€์ ์ธ ์ธํ„ฐํŽ˜์ด์Šค. Feathers์™€ ๋น„์Šทํ•œ ๊ฐœ๋ฐœ ๊ฒฝํ—˜์„ ๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

@Sinding ์ด์ „์˜ ํ›Œ๋ฅญํ•œ ์ž‘์—…์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค!

๊ธฐ์กด ์ธ์ฆ์€ ์ผ๋ฐ˜ ์„œ๋น„์Šค๋กœ ๊ตฌํ˜„๋˜๊ธฐ ๋•Œ๋ฌธ์— ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•˜๊ณ  ๋ช‡ ๊ฐœ์˜ ํ›„ํฌ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ ์ง€์›์„ ์‰ฝ๊ฒŒ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

this.hooks({ after: { create: [issueRefreshToken(), connection('login'), event('login')], remove: [logoutUser(), connection('logout'), event('logout')], patch: [refreshAccessToken()], },

CLI๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ธ์ฆ์„ ์ผœ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ ์ง€์›์„ ์œ„ํ•ด CLI์—์„œ ์œ ์‚ฌํ•œ ์˜ต์…˜์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๋Š” ๊ฐ„๋‹จํžˆ ์˜ˆ๋ผ๊ณ  ๋Œ€๋‹ตํ•˜๋ฉด CLI๊ฐ€ ์ž๋™์œผ๋กœ ๊ณ ๊ฐ "์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ" ์„œ๋น„์Šค๋ฅผ ๋งŒ๋“ค๊ณ  ๊ธฐ๋ณธ ๊ตฌ์„ฑ ํŒŒ์ผ์—์„œ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ ๊ด€๋ จ ๊ตฌ์„ฑ์„ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ ํ„ดํ‚ค ์†”๋ฃจ์…˜๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

@daffl David, ๊นƒํ„ธ์„ ๋งŒ๋“ค์–ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! Feathers์— ๋Œ€ํ•œ "๊ธฐ์—ฌ ๊ฐ€์ด๋“œ", "์ฝ”๋”ฉ ๊ฐ€์ด๋“œ๋ผ์ธ", "์Šคํƒ€์ผ ๊ฐ€์ด๋“œ"๊ฐ€ ์žˆ๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

์ด์ „์— ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ(๋˜๋Š” ์ผ๋ถ€ ์•„์ด๋””์–ด)์„ ๊ตฌํ˜„ํ•˜๋Š” PR์€ ๋งค์šฐ ํ™˜์˜ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์•„์ง ๋งํฌ๋œ ์ €์žฅ์†Œ๋ฅผ ํ™•์ธํ•  ๊ธฐํšŒ๊ฐ€ ์—†์—ˆ๊ณ  ์ด ํ† ๋ก ์ด ๊ฝค ๊ธธ์–ด์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ฒƒ์„ ํ•œ ๊ณณ์—์„œ ์ตœ์‹  ์ƒํƒœ๋กœ ์œ ์ง€ํ•˜๋ฉด ์ผ์ด ํ›จ์”ฌ ์‰ฌ์›Œ์ง‘๋‹ˆ๋‹ค. ๋ช‡ ๊ฐ€์ง€ ์ค‘์š”ํ•œ ๊ธ€๋จธ๋ฆฌ ๊ธฐํ˜ธ:

  • ์ธ์ฆ ์„œ๋น„์Šค ๋ฅผ
  • ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์€ localStorage์— ์ €์žฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ์€ ์ทจ์†Œํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(๋”ฐ๋ผ์„œ https://docs.feathersjs.com/cookbook/authentication/revoke-jwt.html์— ์„ค๋ช…๋œ ์ทจ์†Œ ๋ฉ”์ปค๋‹ˆ์ฆ˜์˜ ๋ณด๋‹ค ์ผ๋ฐ˜์ ์ธ ๋ชฉ์  ๊ตฌํ˜„์ด ํ•„์š”ํ•จ)
  • ์ถ”๊ฐ€ ๋ณต์žก์„ฑ ๋ฐ ์„ค์ •(์ทจ์†Œ๋œ ํ† ํฐ ์ €์žฅ์„ ์œ„ํ•œ Redis์™€ ๊ฐ™์€)์œผ๋กœ ์ธํ•ด ๊ธฐ๋Šฅ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๊ธฐ๋ณธ์ ์œผ๋กœ ํ™œ์„ฑํ™”๋˜์–ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค(์ฆ‰, ํ‘œ์ค€ ์ƒ์„ฑ ์•ฑ - CLI์˜ ์ผ๋ถ€์ผ ์ˆ˜ ์žˆ์ง€๋งŒ ์ด์— ๋Œ€ํ•ด ์•„๋ฌด๊ฒƒ๋„ ํ•˜๊ธฐ ์ „์—, ๋‚˜๋Š” ์—ฌ์ „ํžˆ hygen ๊ธฐ๋ฐ˜ ๋ฐœ์ „๊ธฐ๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ฐพ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.)
  • ๊ธฐ์—ฌ ์ •๋ณด๋Š” ๊ธฐ์—ฌ์ž ๊ฐ€์ด๋“œ ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ˆ„๊ตฐ๊ฐ€๊ฐ€ refreshToken์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด ์šฐ๋ฆฌ๋Š” ์‚ฌ์šฉํ•˜๊ธฐ ๋„ˆ๋ฌด ์‰ฌ์šด "์„ธ์…˜"๊ณผ ๊ฐ™์€ ํ”„๋ก ํŠธ์—”๋“œ, accessToken ๋ฐ refreshToken์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

ํ† ํฐ์„ ์ „๋‹ฌํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ๋งŒ๋ฃŒ๋  ๋•Œ refreshToken์„ ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ acessToken์„ ์–ป์œผ๋ ค๊ณ  ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ Videsk ์—์„œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

์ €์žฅ์†Œ: ์ „๋ฉด ์ธ์ฆ ์ฒ˜๋ฆฌ๊ธฐ

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰