๐ ์์ํ๋ฉด์
์น ํธ์ ์๋ฆผ(Web Push Notification)์ด๋, ๋ง ๊ทธ๋๋ก ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์ ํธ์ ์๋ฆผ์ ๋ฐ์ ์ ์๋ ๊ธฐ์ ์ ์๋ฏธํ๋ค.
ํธ์ ์๋ฆผ์ด๋ผ๊ณ ํ๋ฉด ๋ค์ดํฐ๋ธ ์ฑ์ ์ ์ ๋ฌผ์ด๋ผ๊ณ ๋๋ ์ ์์ง๋ง, ์น ํธ์ ๊ธฐ์ ์ ํตํด ์น์์๋ ํธ์ ์๋ฆผ ๊ธฐ๋ฅ์ ๊ตฌํํ๊ณ ์ฌ์ฉํ ์ ์๋ค.
๋ธ๋ผ์ฐ์ ์ ๊ตฌํ๋์ด์๋ Push API์ ์์ธํ ์คํ์ ์๋ ๋ฌธ์์์ ํ์ธํด๋ณผ ์ ์๋ค.
๋ณธ ํฌ์คํ
์์๋ ์น ํธ์๊ฐ ๋์ํ๋ ๋ฉ์ปค๋์ฆ์ ๋ํด ์กฐ๊ธ ์ธ๋ถ์ ์ผ๋ก ์ดํด๋ณด๊ณ , ์ง์ ๋ฐ๋ชจ ์ฝ๋๋ฅผ ์ดํด๋ณด๋ฉฐ ์น ํธ์์ ๋ํ ์ ๋ฐ์ ์ธ ์ดํด๋ฅผ ํ ์ ์๋๋ก ์งํํ ์์ ์ด๋ค.
๋ถ๋์ ์กฐ์ ํ๊ธฐ ์ํด ๋ชจ๋ API ๊ธฐ๋ฅ์ ๋ํด ์ค๋ช
ํ์ง ์์ผ๋ ์์ธํ ๋ด์ฉ์ ๊ธ ์ค๊ฐ์ค๊ฐ์ ์ถ๊ฐํด๋ ์ฐธ์กฐ ๋งํฌ(๋ฌธ์)๋ฅผ ์ฐธ๊ณ ํ๊ธธ ๋ฐ๋๋ค.
๋ณธ ํฌ์คํ
์์ ๋ค๋ฃจ๋ ๋๋ถ๋ถ์ ๋ด์ฉ์ ๊ณผ๊ฑฐ์ ์ถ๊ฐํ๋ ์ ์์ ๋ด์ฉ๊ณผ ๋์ผํ๋ฉฐ, PWA์ ๊ด์ฌ์ด ์๋ค๋ฉด ํ ๋ฒ ์ดํด๋ณด๋ฉด ์ข์ ๊ฒ ๊ฐ๋ค.
[PWA] SNS ์ฑ ์์ ๋ก ๋ฐฐ์ฐ๋ ํ๋ก๊ทธ๋ ์๋ธ ์น ์ฑ ์ถ๊ฐ!
์๋ ํ์ธ์~!! ์ด๋ฒ์ ํ๋ก๊ทธ๋ ์๋ธ ์น ์ฑ(PWA)์ ์ฃผ์ ๋ก ํ "SNS ์ฑ ์์ ๋ก ๋ฐฐ์ฐ๋ ํ๋ก๊ทธ๋ ์๋ธ ์น ์ฑ" ์ ์ถ๊ฐํ๊ฒ ๋์ด ๊ฐ๋ตํ ์๊ฐํ๋ ค๊ณ ํฉ๋๋ค! ๐ ๋ณธ ๋ธ๋ก๊ทธ์๋ ํ๋ก๊ทธ๋ ์๋ธ ์น ์ฑ์ ๋
geundung.dev
๐ ์ ํ๊ณผ ์น ํธ์
์๋๋ก์ด๋ ๋ฐ Chromium ๊ธฐ๋ฐ ๋ธ๋ผ์ฐ์ ๋ฑ์์๋ ๊ฝค ์ค๋์ ๋ถํฐ ์น ํธ์๋ฅผ ์ง์ํด์๊ธฐ ๋๋ฌธ์ ์น์์ ํธ์ ์๋ฆผ์ ์ ๊ณตํ ์ ์์์ผ๋, ์ ํ์ Safari ๋ธ๋ผ์ฐ์ ๋ ์ด๋ฅผ ์ง์ํ์ง ์์๋ค.
์ฌ์ค ๋ณธ์ธ์ ์ ํ์ด PWA๋ฅผ ๋ด๋ค ๋ฒ๋ฆฐ ์ค ์์๋ค.
์ ํ์ ํญ์ ํ์์ ์ธ ๋ชจ์ต์ ๋ณด์ด๋๋ฐ, ์น์๊ฒ ๋๋ฌด ๋ง์ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ฌ ๋ค์ดํฐ๋ธ ์ฑ๊ณผ์ ๊ฒฝ๊ณ๋ฅผ ํ๋ฌผ๋ฆฌ ์๋ค๊ณ ์๊ฐํ๋ค.
์ญ์๋ ์ ํ์ ๊ตฌ๊ธ๊ณผ ๋ง์ดํฌ๋ก์ํํธ ๋ฑ์ ์น ์ํ๊ณ๋ฅผ ์ฃผ๋์ ์ผ๋ก ์ด๋์ด๊ฐ๋ ์กฐ์ง๊ณผ ๋ค๋ฅด๊ฒ PWA ๊ด๋ จ ๊ธฐ์ (ํธ์ ์๋ฆผ ํฌํจ)์ ๋ํด ์ ๊ทน์ ์ผ๋ก ๋์ํ์ง ์์๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ก Safari ๋ธ๋ผ์ฐ์ ์์๋ง ์ง์ํ์ง ์๋ API๊ฐ ์ฌ๋ฟ ์๊ธฐ๊ฒ ๋์๋ค.
ํ ์ํฉ์์ macOS ๊ทธ๋ฆฌ๊ณ iOS์ iPadOS ์ ์ ๋ค์ด ์ฌ์ฉํ๋ Safari ๋ธ๋ผ์ฐ์ ์ ์ ์ ์จ์ ๊ฒฐ์ฝ ๋ฌด์ํ ์ ์๋ ์์ค์ด๊ธฐ์, ์น(PWA)์ด ํ์ ์ป๊ณ ์ํฅ๋ ฅ์ ํผ์น๋ ค๋ฉด Safari ๋ธ๋ผ์ฐ์ ์ ์ ๊ทน์ ์ธ PWA ์ง์์ด ํ์ํ ์ํฉ์ด์๋ค.
PWA์ ๋ํด ๊ด์ฌ์ด ๋ง์๋ ๋ณธ์ธ์, WWDC20๋ถํฐ ์น ํธ์์ ๋ํ ๋ด์ฉ์ ๊ธฐ๋ค๋ ค์์ผ๋ ํญ์ ๊ธฐ๋ํ๋ ๊ฒ๊ณผ๋ ๋ค๋ฅธ ๋ด์ฉ๋ง ์ป์๊ธฐ์ ๋ค์ ์์ฌ์์ด ๋ง์๋ค. ๊ทธ๋ฌ๋ ์ค ์ต๊ทผ ์งํ๋์๋ ์ ํ ๊ฐ๋ฐ์ ํ์ฌ์ธ WWDC22์ Meet Web Push for Safari ์ธ์
์์ ๋๋์ด ์น ํธ์์ ๊ดํ ๋ด์ฉ์ด ์ธ๊ธ๋์๋ค.
Web Push is supported in Mac Safari beginning with macOS Ventura. And Web Push will be coming to iOS and iPadOS next year.
์ด๋ฒ์ ๋ฐํํ ๋ด์ฉ์ ๋ฐ๋ฅด๋ฉด ์น ํธ์๋ฅผ ์ง์ํ๋ ์ฌํ๋ฆฌ ๋ฒ์ ์ ์๋์ ๊ฐ๋ค.
- Safari 16 (macOS 13, Ventura ๋ถํฐ)
- iOS ๋ฐ iPadOS๋ ๋ด๋ (2023๋ )๋ถํฐ ์ง์
๋คํ์ธ ์ ์ ์ ํ ๋
์์ ์ธ ์น ํธ์๊ฐ ์๋๋ผ, ๋ค๋ฅธ ๋ธ๋ผ์ฐ์ ๋ค์์ ๊ตฌํ๋์ด์๋ ์น ํธ์ ํ์ค์ ๋ฐ๋ฅธ๋ค๊ณ ํ๋ค. (์ ํ์ ๋ณต์กํ ์ธ์ฆ์ ์์ด๋ ๊ฐ๋จํ ํธ์ ์๋ฆผ์ ์ ๊ณตํ ์ ์๋ค)
์์ง MDN Web Docs์ ์น ํธ์ API ํธํ์ฑ ํ๊ฐ ์
๋ฐ์ดํธ๋์ง ์์๋๋ฐ, ๊ณง ์
๋ฐ์ดํธ๋ ๊ฒ ๊ฐ๊ณ ๋ด๋
์๋ iOS Safari ์๋ ์ฒดํฌ ์์ด์ฝ์ด ์๊ธฐ๊ฒ ๋ ๊ฒ์ผ๋ก ๋ณด์ธ๋ค.
์กฐ๋ง๊ฐ ์ ํธํ์ฑ ํ ์์ Safari X ์์ด์ฝ์ ์ญ์ฌ ์์ผ๋ก ์ฌ๋ผ์ง ๊ฒ์ด๋ค.
์ด์จ๋ , ์ ํ์ด ํฌ๊ธฐํ ์ค๋ง ์์๋ ์น ํธ์๋ฅผ ์ง์ํด์ค๋ค๊ณ ํ๋ ์์ผ๋ก์ ์น ๊ธฐ์ ์ด ์ด๋ป๊ฒ ๋ณํํ ์ง ๊ธฐ๋๊ฐ ๋๋ค.
๐ ์น ํธ์ ๋์ ์ดํด๋ณด๊ธฐ
์น ํธ์๊ฐ ์ ๋ฐ์ ์ผ๋ก ์ด๋ป๊ฒ ๋์ํ๋์ง ๋ฉ์ปค๋์ฆ์ ๋ํด ์ดํด๋ณด๋๋ก ํ์.
๐ ํ(Pull)๊ณผ ํธ์(Push)
๋จผ์ ํ(Pull)๊ณผ ํธ์(Push)์ ์ฐจ์ด๋ฅผ ์๋ ๊ทธ๋ฆผ์ ๋ณด๋ฉฐ ์ดํด๋ณด์.
ํ(Pull)์ ๋๋ถ๋ถ์ ์ ํ๋ฆฌ์ผ์ด์
์์ ์ฝ๊ฒ ์ดํด๋ณผ ์ ์๋ ๋์ ๋ฐฉ์์ด๋ค.
ํด๋ผ์ด์ธํธ ๊ธฐ์ค์ผ๋ก ๋ณด์์ ๋, ํ(Pull) ๋จ์ด์ ์๋ฏธ์ ๋์ผํ๊ฒ ๋ฐ์ดํฐ๋ฅผ ๋น๊ฒจ์ค๋ ๋ชจ์ต์ ๋ณผ ์ ์๋ค.
์๋ฒ์ ์๋ ํน์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊ธฐ ์ํด ๋จผ์ ์์ฒญํ๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋๋ ค๋ฐ๋ ํํ๋ฅผ ์๋ฏธํ๋ค.
ํธ์(Push)๋ ํ๊ณผ ๋์ํ๋ ๋ชจ์ต์ด ์กฐ๊ธ ๋ค๋ฅด๋ค.
์๋ฒ์์ ํด๋ผ์ด์ธํธ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ด ๋ฃ๋(Push) ๋ชจ์ต์ ๋ณผ ์ ์์ผ๋ฉฐ, ํด๋ผ์ด์ธํธ๊ฐ ๋จผ์ ์์ฒญ์ ๋ณด๋ด์ง ์๋๋ผ๋ ์๋ฒ๊ฐ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ด ๋ฃ์ด์ฃผ๋ ํํ์ด๋ค.
๐จ๐ฉ๐ง๐ฆ ์น ํธ์์ ๊ตฌ์ฑ ์์
์น ํธ์๊ฐ ๋์ํ๊ธฐ ์ํด์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ํ์ํ ๊ตฌ์ฑ ์์๊ฐ ์๋ค.
- ๋ธ๋ผ์ฐ์ (์ฌ์ฉ์)
- ํธ์ ์๋ฆผ์ ๋ฐ์กํ ์๋ฒ
- ํธ์ ์๋ฆผ์ ์ฌ์ฉ์์๊ฒ ์ ๋ฌํ ํธ์ ์๋น์ค
ํฌ๊ฒ ๋ณด๋ฉด ์ด 3๊ฐ์ง๋ก ์ด๋ฃจ์ด์ ธ ์๋ค.
์๋ฒ์์ ์ด๋ค ์ฌ์ฉ์์๊ฒ, ์ด๋ค ๋ฉ์์ง๋ฅผ ๋ณด๋ผ์ง์ ๋ํ ๋ด์ฉ์ด ๋ด๊ธด ๋ฉ์์ง ๋ฐ์ดํฐ๋ฅผ ํธ์ ์๋น์ค๋ก ์ ๋ฌํ๋ฉด, ํธ์ ์๋น์ค์์ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ์๋ณํ ํ ๋ชฉ์ ์ง๋ก ์ ๋ฌํ๋ค.
์น ํธ์์ด๊ธฐ ๋๋ฌธ์ ์ฌ๊ธฐ์ ์ด์ผ๊ธฐํ๋ ๋ชฉ์ ์ง๋ ๋ธ๋ผ์ฐ์ ๊ฐ ๋๋ค.
์ด๋ค ์์๋ก ์ด๋ฃจ์ด์ ธ ์๊ณ , ๋๋ต ์ด๋ค ํ๋ฆ์ธ์ง ์ ๊ฒ๋ง ๊ฐ์๋ฐ ๋ฐ์ค๋ก ๊ฐ์กฐํ ๋ถ๋ถ์ ๋ํด์ ์๋ฌธ์ ์ด ์๊ฒผ์ ๊ฒ์ด๋ค.
์ด ๋ถ๋ถ์ ์๊ธฐ ์ํด์๋ ์น ํธ์ ๊ธฐ๋ฅ์ ์ ๊ณตํ๊ธฐ ์ํด ์ ํด์ง ๊ท์ฝ. ์ฆ, ์น ํธ์ ํ๋กํ ์ฝ(Web Push Protocol)์ ๋ํด ์์์ผ ํ๋ค.
๐ค ์น ํธ์ ํ๋กํ ์ฝ
์น ํธ์ ํ๋กํ ์ฝ(Web Push Protocol)์ ํธ์ ์๋ฆผ์ ์์ ํ๋ ๋ธ๋ผ์ฐ์ ์ ๋ฐ์กํ๋ ์๋ฒ๊ฐ ํธ์ ์๋น์ค์ ์ํธ์์ฉํ๊ธฐ ์ํด ์ ํด๋์ ๊ท์ฝ์ด๋ค.
ํด๋ผ์ด์ธํธ(๋ธ๋ผ์ฐ์ ) ์ ๋ณด๋ฅผ ๋ฑ๋กํ๊ณ , ์๋ฒ์์ ๋ฉ์์ง๋ฅผ ๋ฐ์กํ๊ณ , ์ต์ข
์ ์ผ๋ก ์ฌ์ฉ์์๊ฒ ๋๋ฌํ๊ธฐ๊น์ง ์ฌ๋ฌ ์ ์ฐจ๋ฅผ ๊ฑฐ์น๊ฒ ๋๋ค.
์ ์ฐจ์ ๋ํ ๋ถ๋ถ์ ์๋ ๊ทธ๋ฆผ์ ํตํด ๊ฐ๋ตํ ์ดํด๋ณผ ์ ์๋ค.
๋จผ์ ํธ์๋ฅผ ์์ ํ๊ฒ ๋ ํด๋ผ์ด์ธํธ(๋ธ๋ผ์ฐ์ )์์๋ ํธ์ ์๋น์ค๋ก ๋ด๊ฐ ๋๊ตฐ์ง ์๋ฆฐ๋ค.
์ด ๊ณผ์ ์ ๊ตฌ๋
(Subscription)์ด๋ผ๊ณ ํ๋ฉฐ ์กฐ๊ธ ๋ ์์ธํ ์ ์ฐจ๋ ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ๋ค.
ํธ์ ์๋น์ค๋ก ๊ตฌ๋
์์ฒญ์ ๋ณด๋ด๊ณ , ์ฑ๊ณต์ ์ผ๋ก ๊ตฌ๋
๋ ๊ฒฝ์ฐ ํธ์ ์๋น์ค์์๋ ๊ตฌ๋
์ ๋ณด๋ฅผ ๋ธ๋ผ์ฐ์ ์๊ฒ ๋๋ ค์ค๋ค.
๊ตฌ๋
์ ๋ณด์๋ ๋ธ๋ผ์ฐ์ ๋ฅผ ์๋ณํ๋ ์ ๋ณด๊ฐ ๋ด๊ฒจ์์ผ๋ฉฐ, ์๋ฒ์์ ํน์ ๋ธ๋ผ์ฐ์ (์ฌ์ฉ์)์๊ฒ ํธ์ ๋ฉ์์ง๋ฅผ ๋ฐ์กํ ๋ ์ด ์ ๋ณด๊ฐ ํ์ํ๋ค.
๊ตฌ๋
์ ๋ณด๋ ์๋ฒ์ ์ ์ฅํด๋์๋ค๊ฐ, ํธ์ ์๋ฆผ ๋ฐ์ก์ด ํ์ํ ๋ ๊บผ๋ด์ ์ฌ์ฉํ๋ ํํ๊ฐ ๋๋ค.
์ฌ๊ธฐ๊น์ง์ ๊ณผ์ ์ด ๋ง๋ฌด๋ฆฌ๋์๋ค๋ฉด, ๋ธ๋ผ์ฐ์ ๊ฐ ํธ์ ์๋ฆผ์ ์์ ํ๊ธฐ ์ํ ๊ณผ์ ์ ๋ชจ๋ ๋๋ฌ๋ค.
์ด์ ์๋ฒ์์ ํธ์ ์๋น์ค๋ก ๊ตฌ๋
์ ๋ณด์ ๋ฉ์์ง๋ฅผ ์ ๋ฌํ๋ฉด ํด๋นํ๋ ๋ธ๋ผ์ฐ์ ๋ก ํธ์ ์๋ฆผ์ด ์ ๋ฌ๋ ๊ฒ์ด๋ค.
๐ ์์ ํ ๋ฉ์์ง๋ฅผ ์ํ VAPID
์ฐ๋ฆฌ๊ฐ ๋์น์ง ๋ง์์ผ ํ ๋ถ๋ถ์ ์๋ฒ์์ ํธ์ ๋ฉ์์ง๋ฅผ ์ ๋ฌํ ๋ ๊ทธ๋ฅ ์ ๋ฌํ์ง ์๋๋ค๋ ์ ์ด๋ค. ํธ์ ๋ฉ์์ง๋ ๋ฏผ๊ฐํ๊ธฐ ๋๋ฌธ์ ์์ ํ๊ฒ ์ํธํ๋์ด์ผ ํ๊ณ , ๋ฉ์์ง๊ฐ ์ด๋ค ์๋ฒ์์ ๋ฐ์ก๋์๋์ง ์ ์ ์์ด์ผ ํ๋ค.
์น ํธ์์์๋ ์ด๋ค ์๋ฒ์์ ๋ฉ์์ง๋ฅผ ๋ฐ์กํ๋์ง ์๋ณํ๊ธฐ ์ํด VAPID(Voluntray Application Server Identification) ์ธ์ฆ ๋ฐฉ์์ ์ฌ์ฉํ๋ค.
VAPID๋ ์๋ฐ์ ์ผ๋ก ์๋ฒ(ํธ์ ๋ฉ์์ง๋ฅผ ๋ฐ์กํ๋)๋ฅผ ์๋ณํ๋ ์ธ์ฆ ๋ฐฉ์์ด๋ค.
VAPID๋ ๊ฐ๋จํ๊ฒ ๋ณด๋ฉด ๊ณต๊ฐํค ์ํธํ ๋ฐฉ์์ ํค ์์ผ๋ก ๊ฒ์ฆ ์ ์ฐจ๋ฅผ ๊ฑฐ์น๋๋ฐ, ๋จผ์ ๊ณต๊ฐํค ์ํธํ ๋ฐฉ์์ ๋ํด ๊ฐ๋ตํ ์์๋ณด์.
๊ณต๊ฐํค ์ํธํ๋ ๋น๊ณต๊ฐ ํค(Private Key)์ ๊ณต๊ฐ ํค(Public Key) ์์ ๊ฐ๋๋ค.
๊ณต๊ฐํค ์ํธํ์ ๊ฒฝ์ฐ ๋น๊ณต๊ฐ ํค์ ๊ณต๊ฐ ํค์ ๊ฐ์ด ์ผ์นํ์ง ์๋ ๋น๋์นญ ์ํธํ ๋ฐฉ์์ด๋ค.
์ํธํ ๊ณผ์ ์ด ์๋ค๋ฉด ๋ณตํธํ๋ ํ์ํ ๋ฒ์ธ๋ฐ, ๊ณต๊ฐ ํค๋ก ์ํธํํ๋ค๋ฉด ๋น๊ณต๊ฐ ํค๋ก ๋ณตํธํํด์ผ ํ๊ณ , ๋น๊ณต๊ฐ ํค๋ก ์ํธํํ๋ค๋ฉด ๊ณต๊ฐ ํค๋ก ๋ณตํธํํด์ผ ํ๋ค.
์ด๋ฌํ ํน์ฑ์ผ๋ก ์ธํด ์ ์ ์๋ช
์ด๋ ์ธ์ฆ์ด ํ์ํ ๋ถ๋ถ์์ ๋๋ฆฌ ์ฌ์ฉ๋๊ณ ์๋ ์ํธํ ๊ธฐ๋ฒ์ด๋ค.
๋ค์ ๋ณธ ๋ด์ฉ์ผ๋ก ๋์์์, VAPID๋ ๊ณต๊ฐํค ์ํธํ ๋ฐฉ์์ ํค ์์ผ๋ก ์ด๋ฃจ์ด์ ธ ์๋ค.
์๋ฒ์์ ํธ์ ์๋น์ค๋ก ๋ฉ์์ง๋ฅผ ์ ๋ฌํ ๋ VAPID ๋ช
์ธ์ ๋ฐ๋ฅธ ์ ๋ณด๊ฐ ๋ด๊ธด JWT(JSON Web Token)์ ํจ๊ป ์ ๋ฌํ๊ฒ ๋๋๋ฐ, ์ด๋ ์ด ํ ํฐ์ VAPID์ ๋น๊ณต๊ฐ ํค๋ก ์๋ช
(์ํธํ)ํ๋ค.
์๋ช
๋ ํ ํฐ์ ๋ฐ๋๋ก ํธ์ ์๋น์ค์์ ๊ณต๊ฐ ํค๋ก ๋ณตํธํํ์ฌ ์ ํจ์ฑ์ ๊ฒ์ฆํ๊ฒ ๋๋ค.
์ด๋ฌํ ์ ์ฐจ๋ฅผ ํตํด ํธ์ ์๋น์ค์์ ์ด๋ค ์๋ฒ๋ก๋ถํฐ ์์ ํ ๋ฉ์์ง์ธ์ง, ์ ํจํ ๋ฉ์์ง์ธ์ง ๊ฒ์ฆํ ์ ์๊ฒ ๋๋ค.
์ง๊ธ๊น์ง ์ดํด๋ณธ ๋ด์ฉ์ ๋ชจ์ ๋ณด๋ฉด ์๋์ ๊ฐ์ ํ๋ฆ์ผ๋ก ๋ํ๋ผ ์ ์๋ค.
- (1) ๋ธ๋ผ์ฐ์ ์์ ํธ์ ์๋น์ค ๊ตฌ๋ + VAPID ๊ณต๊ฐ ํค ์ ๋ฌ
- (2) ๊ตฌ๋ ์ ๋ณด ์์
- (3) ๊ตฌ๋ ์ ๋ณด ์๋ฒ๋ก ์ ๋ฌ
- (4) ๊ตฌ๋ ์ ๋ณด + ๋ฉ์์ง + VAPID ๋น๊ณต๊ฐ ํค๋ก ์ํธํ๋ JWT
- (5) VAPID ๊ณต๊ฐ ํค๋ก ์ ํจ์ฑ ๊ฒ์ฆ & ๊ฒ์ฆ๋ ๊ฒฝ์ฐ ๊ตฌ๋ ์ ๋ณด์ ํด๋นํ๋ ๋ธ๋ผ์ฐ์ ๋ก ํธ์ ๋ฉ์์ง ๋ฐ์ก
4, 5๋ฒ ๊ณผ์ ์์ ๋ฐ์ดํฐ๊ฐ ์์กฐ๋๊ฑฐ๋, ํค๊ฐ ์ผ์นํ์ง ์๋ ๊ฒฝ์ฐ ํธ์ ๋ฉ์์ง๋ ์ ํจํ์ง ์์ ์ํ๊ฐ ๋์ด ๋ธ๋ผ์ฐ์ ๊น์ง ๋๋ฌํ์ง ๋ชปํ๊ณ ํธ์ ์๋น์ค์์ ํ๊ธฐ๋๋ค.
VAPID ์ธ์ฆ ๊ณผ์ ์ Node ํ๊ฒฝ์์ ๊ตฌํํด๋ณธ ์ฝ๋๊ฐ ์กด์ฌํ๋๋ฐ ๊ด์ฌ์ด ์๋ค๋ฉด ํ ๋ฒ ์ดํด๋ณด๋ฉด ์ข์ ๊ฒ ๊ฐ๋ค.
์น ํธ์์ ์ ์ฒด์ ์ธ ํ๋ฆ์ ์ง๊ธ๊น์ง ์ดํด๋ณธ ๊ฒ๊ณผ ๊ฐ๋ค.
๋ณต์กํ๊ฒ ๋๊ปด์ง ์๋ ์์ง๋ง ์ฝ๋๋ฅผ ์์ฑํ๋ค๋ณด๋ฉด ํจ์ฌ ์ฝ๊ฒ ์๋ฟ์ ๊ฒ์ด๋ค.
๐ฅ ์น ํธ์ ๊ตฌํํ๊ธฐ
์ํํ ์งํ์ ์ํด ์น ํธ์ ๋ฐ๋ชจ ์ฝ๋๋ฅผ ์ค๋นํ์๋ค.
์๋ ๊นํ๋ธ ์ฃผ์์์ ์ฝ๋๋ฅผ ๋ค์ด๋ก๋ ๋ฐ๊ณ , ์ฝ๋์ ๋์์ ํ์ธํด๋ณด์.
https://github.com/leegeunhyeok/web-push
GitHub - leegeunhyeok/web-push: ๐ Web Push | Getting Started
๐ Web Push | Getting Started. Contribute to leegeunhyeok/web-push development by creating an account on GitHub.
github.com
README ํ์ผ์ ์ ๋ฆฌ๋์ด์๋ ๋ด์ฉ๋๋ก ํ๊ฒฝ์ ์ธํ
ํ๋๋ก ํ์.
์ค๋น๊ฐ ๋์๋ค๋ฉด ๋ฐ๋ชจ ์๋ฒ๋ฅผ ์คํ์ํจ ํ ํ์ด์ง์ ์ ์ํ์ฌ ๋ค์ ๋ด์ฉ๋ค์ ํ๋์ฉ ์ดํด๋ณด์.
์น ํธ์ ๊ธฐ๋ฅ์ ์น ์์ปค ์ค ํ ์ข
๋ฅ์ธ ์๋น์ค ์์ปค(Servier Worker)๋ฅผ ํตํด ๊ตฌํํ ์ ์์ผ๋ฉฐ, ๋ธ๋ผ์ฐ์ ์ ๋ฐฑ๊ทธ๋ผ์ด๋ ํ๊ฒฝ์์ ์ฒ๋ฆฌ๋๋ค.
(์๋น์ค ์์ปค์ ๋ํ ์์ธํ ๋ด์ฉ์ ์ถํ ์์ฑํ ์์ ์ด๋ค)
๋ชจ๋ ๋ธ๋ผ์ฐ์ (์ด์ Safari ํฌํจ)์๋ ์น ํธ์ ์๋ฆผ์ ์ ๊ณตํ๊ธฐ ์ํ API๋ค์ด ๊ตฌํ๋์ด์๋ค.
ํธ์ ์๋น์ค๋ฅผ ๊ตฌ๋
ํ๊ณ , ๋ฉ์์ง๋ฅผ ์์ ํ๊ธฐ ์ํ Push API, ๊ทธ๋ฆฌ๊ณ ์๋ฆผ์ ์ฌ์ฉ์์๊ฒ ๋
ธ์ถ์ํค๊ธฐ ์ํ Notification API๊ฐ ์๋ค.
์ด์ ๋ํ ๋ถ๋ถ์ ๊ฐ๋ตํ ์ดํด๋ณด๊ณ ์ง๋๊ฐ๋๋ก ํ์.
๐ Notification API
๋ธ๋ผ์ฐ์ ์์ ์์คํ
์๋ฆผ์ ๋์ฐ๊ธฐ ์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค. ์ฐ๋ฆฌ๋ ์ด๋ฅผ ํตํด ์ฌ๋ฌ ํ๋ซํผ(์๋์ฐ, ๋งฅ, ๋ฆฌ๋
์ค, ์๋๋ก์ด๋, iOS)์ ๋ง๋ ์์คํ
์๋ฆผ์ ์ฝ๊ฒ ๋์ธ ์ ์๋ค.
Notification API๋ฅผ ํตํด ์ํ ๊ฐ๋ฅํ ๋ํ์ ์ธ ๊ธฐ๋ฅ์ ์๋์ ๊ฐ๋ค.
- ์๋ฆผ ๊ถํ ์์ฒญํ๊ธฐ
- ์๋ฆผ ๊ถํ ์ํ
- ์๋ฆผ ๋์ฐ๊ธฐ
(์์์ผ๋ก ๊ฐ์กฐํ ๋ถ๋ถ์ ๋ํด์๋ง ๊ฐ๋จํ ์ดํด๋ณธ๋ค)
์๋ฆผ ๊ถํ์ ์๋์ ๊ฐ์ด ์ฝ๊ฒ ํ์
ํ ์ ์๋ค.
Notification.permission; // 'default', 'denied', 'granted'
๊ธฐ๋ณธ ์ํ๋ default์ด๋ฉฐ, ์์ง ๋ธ๋ผ์ฐ์ ์์ ์ฌ์ฉ์์๊ฒ ๊ถํ์ ๋ฌผ์ด๋ณด์ง ์์ ์ํ๋ฅผ ์๋ฏธํ๋ค.
๋ธ๋ผ์ฐ์ ์์ ์ฌ์ฉ์์๊ฒ ๊ถํ์ ๋ฌผ์ด๋ณธ ํ ์ฌ์ฉ์๊ฐ ์ ํํ ๋์์ ๋ฐ๋ผ ๋ ๊ฐ์ง ์ํ๋ก ๋๋ ์ง๋ค.
์ฌ์ฉ์๊ฐ ๊ฑฐ๋ถํ ๊ฒฝ์ฐ denied, ํ๊ฐํ ๊ฒฝ์ฐ granted๊ฐ ๋๋ฉฐ, ์ด ์ํ์์๋ ๋ ์ด์ ๊ถํ ๋ณ๊ฒฝ์ด ๋ถ๊ฐํ๋ค. (์ฌ์ฉ์๊ฐ ์ง์ ๋ธ๋ผ์ฐ์ ์ค์ ์ ํตํด ๋ณ๊ฒฝํด์ผ ํ๋ค.)
๊ถํ์ด ํ๊ฐ ์ํ์ธ ๊ฒฝ์ฐ ์๋ฆผ์ ๋์ธ ์ ์๊ฒ ๋๋ค. ์๋ฆผ์ ๋์ฐ๋ ๋ฐฉ๋ฒ์ ํฌ๊ฒ ๋ ๊ฐ์ง๊ฐ ์๋๋ฐ ์๋ฆผ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๊ฒ๊ณผ ์๋น์ค ์์ปค์ showNotification ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ๊ฒ์ด๋ค. ์ฌ๊ธฐ์๋ ํ์ ๋ฐฉ์์ ๋ํด ์์๋ณธ๋ค.
๋จผ์ ์๋ฆผ์ ๋์ฐ๋ ์ฝ๋๋ฅผ ์ดํด๋ณด์.
registration.showNotification(title, {
body: 'Some message',
});
์๋น์ค ์์ปค ๋ฑ๋ก ๊ฐ์ฒด์๋ ์๋ฆผ์ ๋์ธ ์ ์๋ showNotification ๋ฉ์๋๊ฐ ๊ตฌํ๋์ด์๋ค.
์ฒซ ๋ฒ์งธ ์ธ์๋ก๋ ์๋ฆผ์ ์ ๋ชฉ, ๋ ๋ฒ์งธ ์ธ์๋ก๋ ์๋ฆผ์ ๋ณธ๋ฌธ ๊ทธ๋ฆฌ๊ณ ๊ธฐํ ์ต์
๋ค์ด ์ ๋ฌ๋๋ค.
์๋ฆผ ๊ถํ์ด ๋ถ์ฌ(granted)๋์ด์๋ค๋ฉด, ์ ์์ ์ผ๋ก ์์คํ
์๋ฆผ์ด ํ์๋ ๊ฒ์ด๋ค.
๐ Push API
Push API๋ ํธ์ ์๋น์ค๋ก๋ถํฐ ์ ์ก๋ ๋ฉ์์ง๋ฅผ ์์ ํ ์ ์๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.
์ด๋ฅผ ํตํด ์ฌ์ฉ์๊ฐ ํธ์ ์๋ฆผ์ ์์ ํ๊ณ , ์น ์ ํ๋ฆฌ์ผ์ด์
์ ์ฌ์ฐธ์ฌํ ์ ์๋๋ก ๊ธฐ๋ฐ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.
์น ์ ํ๋ฆฌ์ผ์ด์
์ด ํธ์ ๋ฉ์์ง๋ฅผ ์์ ํ๊ธฐ ์ํด์๋ ํ์ฑํ ๋์ด์๋ ์๋น์ค ์์ปค๊ฐ ํ์ํ๋ค.
์๋น์ค ์์ปค๋ ๋ธ๋ผ์ฐ์ ๋ฐฑ๊ทธ๋ผ์ด๋ ํ๊ฒฝ์์ ๋์ํ๊ณ , ํธ์ ๋ฉ์์ง๋ฅผ ์์ ํ์ ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ํตํด ์์ ํ ๋ฉ์์ง๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ค.
Push API์ ์ฃผ์ ๊ธฐ๋ฅ์ ๋์ดํด๋ณด๋ฉด ์๋์ ๊ฐ๋ค.
- ํธ์ ์๋น์ค ๊ตฌ๋ ๋ฐ ํด์ง
- ํธ์ ๋ฉ์์ง ์์
โ๏ธ ์๋น์ค ์์ปค ๋ฑ๋กํ๊ธฐ
ํธ์๋ฅผ ์์ ํ๊ธฐ์ ์์ ์๋น์ค ์์ปค ๋ฑ๋ก์ด ํ์ํ๋ค. ์๋น์ค ์์ปค๋ ๋ค๋ฅธ ์น ์์ปค์ ๋ง์ฐฌ๊ฐ์ง๋ก ์์ปค ์คํฌ๋ฆฝํธ๋ฅผ ๋ก๋ํ์ฌ ์ค์น & ํ์ฑํ์ํฌ ์ ์๋ค.
async function registerServiceWorker () {
if (!('serviceWorker' in navigator)) return;
// ์ด๋ฏธ ๋ฑ๋ก๋์ด์๋ ์ ๋ณด ๊ฐ์ ธ์ค๊ธฐ
let registration = await navigator.serviceWorker.getRegistration();
if (!registration) {
// ์์ผ๋ฉด ์๋น์ค ์์ปค ๋ฑ๋ก
registration = await navigator.serviceWorker.register('/service-worker.js');
}
}
navigator ๊ฐ์ฒด์ serviceWorker๊ฐ ์กด์ฌํ๋์ง ํ์ธํ์ฌ ํ์ฌ ๋ธ๋ผ์ฐ์ ๊ฐ ์๋น์ค ์์ปค๋ฅผ ์ง์ํ๋์ง ํ์ธํ ์ ์๋ค.
์กด์ฌํ์ง ์์ ๊ฒฝ์ฐ ๊ธฐ๋ฅ ์ฌ์ฉ์ด ๋ถ๊ฐํ๋ ๋ถ๊ธฐ ์ฒ๋ฆฌ๊ฐ ๋ฐ๋์ ํ์ํ๋ค.
navigator.serviceWorker.getRegistration์ ํตํด ์๋น์ค ์์ปค์ ๋ฑ๋ก ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ค.
์์ง ์๋น์ค ์์ปค๊ฐ ๋ฑ๋ก๋์ด์์ง ์๋ค๋ฉด null์ ๋ฐํํ๊ธฐ ๋๋ฌธ์ ๊ฐ์ ์ ๋ฌด๋ฅผ ํตํด ๊ธฐ์กด ๋ฑ๋ก ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ ์ง, ์๋ก ์๋น์ค ์์ปค๋ฅผ ๋ฑ๋กํ ์ง ๊ฒฐ์ ํ ์ ์๋ค.
์๋น์ค ์์ปค ๋ฑ๋ก์ navigator.serviceWorker.register๋ฅผ ํตํด ์งํํ ์ ์๋ค. ์ฒซ ๋ฒ์งธ ์ธ์์๋ ์๋น์ค ์์ปค ์คํฌ๋ฆฝํธ๊ฐ ์์นํ ๊ฒฝ๋ก๋ฅผ ๋ฌธ์์ด๋ก ์ ๋ฌํ๋ฉด ๋๊ณ , ๋ค์ด๋ก๋์ ์ค์น ๊ณผ์ ์ ๋ธ๋ผ์ฐ์ ์์ ์์์ ์ฒ๋ฆฌํ๋ค.
๐ ํธ์ ์๋น์ค ๊ตฌ๋ ํ๊ธฐ
์๋น์ค ์์ปค๊ฐ ๋ฑ๋ก๋์๋ค๋ฉด ๋ฑ๋ก ๊ฐ์ฒด๋ฅผ ํตํด ํธ์ ๋งค๋์ (Push Manager)์ ์ ๊ทผํ ์ ์๋ค.
registration.pushManager;
์๋น์ค ์์ปค ๋ฑ๋ก ๊ฐ์ฒด์ pushManager๊ฐ ์๋ค๋ฉด, ํธ์ ์๋ฆผ์ ์ง์ํ์ง ์๋ ๋ธ๋ผ์ฐ์ ์ด๋ ์ด ๋ํ ์กฐ๊ฑด์ ํตํด ๋ถ๊ธฐ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ๋ค.
์์ ์ดํด๋ณด์๋ ๋ด์ฉ ์ค ํธ์ ์๋ฆผ์ด ๋์ํ๋ ํ๋ฆ์ ๋์ง์ด๋ณด๋ฉด, ์ฒซ ๋ฒ์งธ๋ก ํด๋ผ์ด์ธํธ(๋ธ๋ผ์ฐ์ )์์ ํธ์ ์๋น์ค๋ฅผ ๊ตฌ๋
ํ๋ ๊ฒ์ ๊ธฐ์ตํ ๊ฒ์ด๋ค.
ํธ์ ์๋น์ค ๊ตฌ๋
์ ํธ์ ๋งค๋์ ๋ฅผ ํตํด ์ฒ๋ฆฌ ๊ฐ๋ฅํ๊ณ , ์ฝ๋๋ก ๊ตฌํํ์๋ฉด ์๋์ ๊ฐ๋ค.
const subscription = await registration.pushManager.subscribe({
applicationServerKey: VAPID_PUBLIC_KEY,
userVisibleOnly: true,
});
ํธ์ ๋งค๋์ ์ ๊ตฌํ๋์ด์๋ subscribe ๋ฉ์๋๋ฅผ ํตํด ํธ์ ์๋น์ค์๊ฒ ๊ตฌ๋
์์ฒญ์ ๋ณด๋ผ ์ ์๊ณ , ์ด ๊ณผ์ ์์ ์๋ฆผ์ ์์ ํ๊ธฐ ์ํด ๋ธ๋ผ์ฐ์ ๊ฐ ์ฌ์ฉ์์๊ฒ ๊ถํ์ ํ์ธํ๋ ์ ์ฐจ๋ฅผ ์ํํ๊ฒ ๋๋ค.
๊ตฌ๋
์์ฒญ์ ์ํด subscribe๋ฅผ ํธ์ถํ ๊ฒฝ์ฐ ๋ฐ๋์ ์ฌ์ฉ์ ์ ์ค์ฒ๊ฐ ํ์ํ๋ฐ, ์ด๋ ๊ฐ๋ฐ์๊ฐ ์
์์ ์ผ๋ก ํธ์ ์๋น์ค์ ๊ตฌ๋
ํ๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ์ํจ์ด๋ค. ์ฆ, ๋ฐ๋์ ์ฌ์ฉ์๊ฐ ์ด๋ ํ ํ์๋ฅผ ํด์ผ ๊ตฌ๋
์์ฒญ์ด ํ์ฉ๋๋ค. (์: ๋ฒํผ ํด๋ฆญ ๋ฑ)
๊ตฌ๋
์์ฒญ์ ๋ณด๋ด๊ธฐ ์ํด์๋ ์๋ฒ๋ฅผ ์๋ณํ๊ธฐ ์ํ VAPID ๊ณต๊ฐํค(applicationServerKey)์, ํธ์ ๋ฉ์์ง๊ฐ ์ฌ์ฉ์์๊ฒ ๋ณด์ด๋ ์ฉ๋๋ก ์ฌ์ฉ๋๋ค๋ ๊ฒ์ ์๋ฏธํ๋ ํ๋๊ทธ ๊ฐ(userVisibleOnly)์ด ํ์ํ๋ค.
๋ฐ๋ชจ ์ฝ๋ ํ๊ฒฝ์ ์ค๋นํ๋ฉด์ VAPID ํค ์์ ์์ฑํ์ํ
๋ฐ default.json์ ์ ์์ ์ผ๋ก ๋ฃ์ด๋์๋ค๋ฉด, API๋ฅผ ํตํด ๊ณต๊ฐํค๋ฅผ ๋ฐ์์จ ํ applicationServerKey ํ๋กํผํฐ ๊ฐ์ผ๋ก ์ฌ์ฉ๋ ๊ฒ์ด๋ค.
userVisibleOnly ๊ฐ์ ๋ฐ๋์ true ์ด์ด์ผ ํ๊ณ , ์์ ํ ํธ์ ๋ฉ์์ง๋ ์๋ฆผ์ ํตํด ๋ฐ๋์ ์ฌ์ฉ์์๊ฒ ๋ณด์ฌ์ฃผ์ด์ผ ํจ์ ์๋ฏธํ๋ค.
์ ์์ ์ผ๋ก ๊ตฌ๋
๋์๋ค๋ฉด, ๊ตฌ๋
์ ๋ณด๋ฅผ ๋ฐ์๋ณผ ์ ์๋ค.
๊ตฌ๋
์ ๋ณด๋ ์๋์ ๊ฐ์ ํํ๋ก ๊ตฌ์ฑ๋์ด ์์ผ๋ฉฐ, ์๋ฒ์์๋ ํธ์ ๋ฉ์์ง๋ฅผ ๋ฐ์กํ ๋ ํด๋น ๊ตฌ๋
์ ๋ณด๋ฅผ ํจ๊ป ์ ๋ฌํ๊ฒ ๋๋ค.
{
"endpoint": "https://web.push.apple.com/QHnG_a...BVMI",
"keys": {
"p256dh": "BC56...kSB9-Vcq8",
"auth": "fz8...sA"
}
}
๋ฐ๋ชจ ์ฝ๋๋ฅผ ์ดํด๋ณด๋ฉด ์๋์ ๊ฐ์ด ๊ตฌ๋
์ ๋ณด๋ฅผ ์๋ฒ๋ก ์ ๋ฌํ๋ ์ฝ๋๋ฅผ ํ์ธํ ์ ์๋ค.
async function postSubscription (subscription?: PushSubscription) {
...
const response = await fetch('/subscription', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ userId, subscription }),
});
}
๋ฐ๋ชจ ์ฝ๋์์๋ ์ ๋ฌํ ๊ตฌ๋ ์ ๋ณด๋ฅผ ์ฌ์ฉ์ ID์ ๋งคํํ์ฌ ์๋ฒ ์ธก์ ์ ์ฅํด๋๊ฒ ๋๋ค.
๐ ํธ์ ์๋น์ค ๊ตฌ๋ ์ทจ์ํ๊ธฐ
ํธ์ ์๋น์ค ๊ตฌ๋
์ทจ์๋ ๋ ๊ฐ๋จํ๊ฒ ๊ตฌํํ ์ ์๋ค.
ํธ์ ์๋น์ค ๊ตฌ๋
ํ ์ ๋ฌ๋ฐ์ ๊ตฌ๋
์ ๋ณด์ ๊ตฌํ๋์ด์๋ unsubscribe ๋ฉ์๋๋ฅผ ํธ์ถํ๊ธฐ๋ง ํ๋ฉด ๋๋ค.
const unsubscribed = await subscription.unsubscribe();
Promise ๊ฒฐ๊ณผ ๊ฐ์ผ๋ก๋ ์ทจ์ ์ฑ๊ณต ์ฌ๋ถ๋ฅผ boolean ๊ฐ์ผ๋ก ๋ฐํํ๋ค.
๋ฐ๋ชจ ์ฝ๋์์๋ ๊ตฌ๋
์ ์ทจ์ํ ๊ฒฝ์ฐ ์๋ฒ์๋ ์ด ์ฌ์ค์ ์๋ ค ์ ์ฅํด๋์๋ ์ฌ์ฉ์์ ๊ตฌ๋
์ ๋ณด๋ฅผ ํจ๊ป ์ ๊ฑฐํ๋๋ก ๊ตฌํ๋์ด์๋ค.
โ๏ธ ํธ์ ๋ฉ์์ง ๋ณด๋ด๊ณ & ๋ฐ๊ธฐ
ํธ์ ๋ฉ์์ง๋ฅผ ๋ณด๋ด๊ธฐ ์ํด์๋, ์๋ฒ์์ ์น ํธ์ ํ๋กํ ์ฝ์ ๋ฐ๋ผ ํธ์ ์๋น์ค๋ก ๋ฉ์์ง๋ฅผ ์ ๋ฌํด์ผ ํ๋ค.
์ง์ ๊ตฌํํ๋ค๋ฉด ์๋นํ ๋ณต์กํ ํ
๋ฐ, ๋คํํ ์น ํธ์ ํ๋กํ ์ฝ ํ์ค์ ๋ง๊ฒ ๊ตฌํ๋์ด์๋ ์ฌ๋ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ด ์กด์ฌํ๋ค.
๋ฐ๋ชจ ์ฝ๋์์๋ web-push ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌํํ์ผ๋ ์ฐธ๊ณ ๋ฐ๋๋ค.
์๋ฒ ์ชฝ์์ ํธ์ ๋ฉ์์ง๋ฅผ ์ด๋ป๊ฒ ๋ณด๋ด๊ณ ์๋์ง ์ฝ๋๋ฅผ ํ์ธํด๋ณด์.
import webpush from 'web-push';
webpush.setGCMAPIKey(GCM_KEY);
webpush.setVapidDetails(
SUBJECT,
VAPID_PUBLIC,
VAPID_PRIVATE
);
webpush.sendNotification(subscription, JSON.stringify({
title: 'Web Push | Getting Started',
body: message || '(Empty message)',
}));
์๋ฒ ์ฝ๋๋ฅผ ์ดํด๋ณด๋ฉด ์์ ๊ฐ์ ์ฝ๋๊ฐ ์กด์ฌํ๋๋ฐ, web-push ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด ์์ฃผ ๊ฐ๋จํ ๋ฐ์ก ์ฝ๋๋ฅผ ๊ตฌํํ ์ ์๋ค.
ํธ์ ์๋ฆผ์ ๋ฐ์กํ๊ธฐ ์ ์ ๊ธฐ๋ณธ์ ์ธ ๊ตฌ์ฑ(GCM ํค ๋ฐ VAPID ํค ๋ฑ๋ก)์ ์งํํ๊ณ , ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ค์ ๊ตฌํ๋์ด์๋ sendNotification ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ํธ์ ๋ฉ์์ง๋ฅผ ๋ฐ์กํ๋ค.
๋ฐ์กํ ๋, ๊ตฌ๋
์ ๋ณด์ ๋ฉ์์ง ๋ฐ์ดํฐ๋ฅผ ํจ๊ป ์ ๋ฌํ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
๋ฐ์กํ ํธ์ ๋ฉ์์ง๋ ํธ์ ์๋น์ค๋ฅผ ๊ฑฐ์ณ ๋ชฉ์ ์ง์ธ ๋ธ๋ผ์ฐ์ ์ ๋๋ฌํ๊ฒ ๋๋ค.
๋ธ๋ผ์ฐ์ ์ ํธ์ ๋ฉ์์ง๊ฐ ๋๋ฌํ ๊ฒฝ์ฐ ์๋น์ค ์์ปค์ push ์ด๋ฒคํธ๋ฅผ ํตํด ์ด๋ฅผ ์ฒ๋ฆฌํ ์ ์๋๋ฐ, ์๋น์ค ์์ปค ์ฝ๋๋ฅผ ์ ์ ์ดํด๋ณด๋๋ก ํ์.
self.addEventListener('push', (event: PushEvent) => {
const message = event.data?.json() as PushMessage;
event.waitUntil(
self.registration.showNotification(message.title, {
body: message.body,
})
);
});
self.addEventListener('notificationclick', (event: NotificationEvent) => {
self.clients.openWindow('https://github.com/leegeunhyeok/web-push');
});
์๋น์ค ์์ปค ์ฝ๋์ ์ผ๋ถ๋ถ์ ๊ฐ์ ธ์๋ค.
์ฌ๊ธฐ์ ํ์ธํ ๋ถ๋ถ์ push ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ถ๋ถ์ด๋ค. push ์ด๋ฒคํธ๋ ํธ์ ์๋น์ค๋ก๋ถํฐ ๋ฉ์์ง๋ฅผ ์์ ํ์ ๋ ํธ๋ฆฌ๊ฑฐ ๋๋ฉฐ, ๋ธ๋ผ์ฐ์ ๊ฐ ๋ซํ์๋๋ผ๋ ์๋น์ค ์์ปค์์ ์ด๋ฅผ ์์ ํ์ฌ ์ฒ๋ฆฌํ ์ ์๋ค.
self.registration ๋ถ๋ถ์ ์๋น์ค ์์ปค ๋ฑ๋ก ๊ฐ์ฒด๋ฅผ ์๋ฏธํ๋ฉฐ, showNotification์ ์์ ์ดํด๋ณด์๋ Notification API์ ๊ธฐ๋ฅ ์ค ํ๋์ด๋ค. ์ฆ, ํด๋น ์ฝ๋๋ ์ด๋ฒคํธ ๊ฐ์ฒด์์ ์์ ํ ๋ฉ์์ง ๋ฐ์ดํฐ๋ฅผ ๊บผ๋ด์จ ํ ์๋ฆผ์ ๋์ฐ๋ ์ฝ๋๋ผ๊ณ ๋ณผ ์ ์๋ค.
์๋์ notificationclick ์ด๋ฒคํธ๋ ์ด๋ฒคํธ ๋ช
์์ ์ ์ถํ ์ ์๋ฏ์ด ์ฌ์ฉ์๊ฐ ์๋ฆผ์ ๋๋ ์ ๋ ํธ๋ฆฌ๊ฑฐ๋๋ ์ด๋ฒคํธ์ด๋ค.
์ฌ์ฉ์๊ฐ ํธ์ ์๋ฆผ์ ์์ ํ๊ณ , ์ด๋ฅผ ํด๋ฆญํ์ ๋ ์ด๋ ํ ๋์์ ์ฒ๋ฆฌํด์ผ ํ ๋ ํด๋น ์ด๋ฒคํธ ํธ๋ค๋ฌ์์ ๋ก์ง์ ๊ตฌํํ๋ฉด ๋๋ค.
(์: ํธ์ ์๋ฆผ ํด๋ฆญ ์ ํน์ ์น ํ์ด์ง ์ด์ด์ฃผ๊ธฐ)
โญ๏ธ ํธ์ ์๋ฆผ ๋์ ํ์ธํด๋ณด๊ธฐ
์ง๊ธ๊น์ง ํต์ฌ ๊ธฐ๋ฅ๊ณผ ์ฝ๋๋ฅผ ์ดํด๋ณด์๋ค.
ํธ์ ์๋น์ค๋ฅผ ๊ตฌ๋
ํ๊ณ , ์ค์ ๋ก ํธ์ ๋ฉ์์ง๋ฅผ ๋ฐ์ ์์คํ
์๋ฆผ์ด ๋จ๋์ง ์ ๋ฐ์ ์ผ๋ก ํ์ธํด๋ณด์.
๋ฐ๋ชจ ์๋ฒ๋ฅผ ์คํํ๊ณ ํ์ด์ง์ ์ ์ํ๋ฉด, ๋ก๊ทธ์ธ ํ๋ฉด์ผ๋ก ์ด๋ํ ๊ฒ์ด๋ค. ์ฌ๊ธฐ์์ ์ฌ์ฉ์๋ฅผ ์๋ณํ๊ธฐ ์ํด ์์์ ์์ด๋๋ฅผ ์
๋ ฅํ๊ณ ํ ํ๋ฉด์ผ๋ก ์ด๋ํ์.
์ ์ ID๋ฅผ safari_user๋ก ์
๋ ฅํ ํ ์ด๋ํ ํ ํ๋ฉด ๋ชจ์ต์ด๋ค.
๊ฐ ์น์
์ ๋ํด ๊ฐ๋ตํ ์๊ฐํ๋๋ก ํ๊ฒ ๋ค.
- Status: ์๋น์ค ์์ปค ๋ฑ๋ก ์ฌ๋ถ, ํธ์ ์๋ฆผ ์ง์ ์ฌ๋ถ, ํธ์ ์๋ฆผ ๊ถํ ๊ทธ๋ฆฌ๋ ๊ตฌ๋ ์ ๋ณด๋ฅผ ํ์ธํ ์ ์๋ค.
- Subscribe: ํธ์ ์๋น์ค ๊ตฌ๋ & ํด์ง
- Send Push Notification: ํน์ ์ฌ์ฉ์ ID๋ก ํธ์ ๋ฉ์์ง ์ ์ก
- Logout: ๋ก๊ทธ์ธ ํ๋ฉด์ผ๋ก ์ด๋
๋จผ์ ํธ์ ์๋น์ค ๊ตฌ๋ ์ ์ํด Subscribe ๋ฒํผ์ ๋๋ฌ๋ณด์. ๊ทธ๋ฌ๋ฉด ์๋์ ๊ฐ์ด ์๋ฆผ ๊ถํ์ ๋ฌผ์ด๋ณผ ๊ฒ์ด๋ค. ๋์์ ํ์ธํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ํ์ฉํด์ฃผ๋๋ก ํ์.
(๋ง์ฝ ๊ฑฐ๋ถํ๊ฑฐ๋ ์ทจ์ํ ๊ฒฝ์ฐ ๊ถํ์ ๊ฑฐ๋ถ(denied) ์ํ๊ฐ ๋๋๋ฐ, ๋ธ๋ผ์ฐ์ ์ค์ ์ผ๋ก ์ด๋ํ์ฌ ๊ถํ์ ์ฌ์ค์ ํ ํ ํ์ด์ง๋ฅผ ์๋ก ๊ณ ์นจ ํ๋ฉด ๋๋ค)
์ ์์ ์ผ๋ก ๊ตฌ๋
๋ ๊ฒฝ์ฐ ์๋์ ๊ฐ์ด ๊ตฌ๋
์ ๋ณด๋ฅผ Status ์น์
์์ ํ์ธํ ์ ์๋ค. ํ์ฌ ๋์์ ธ ์๋ ๋ธ๋ผ์ฐ์ ๋ ํธ์ ์๋ฆผ์ ์์ ํ ์ ์๋ค.
Send Push Notification ์น์
์์ Target User ID ๋ถ๋ถ์ ํ์ฌ ๋ณธ์ธ์ ์์ด๋๋ฅผ ์
๋ ฅํ ํ Send ๋ฒํผ์ ๋๋ฌ๋ณด์.
์๋ฒ๋ฅผ ํตํด ํธ์ ์๋น์ค๋ก ๋ฉ์์ง๊ฐ ์ ๋ฌ๋๊ณ , ํธ์ ์๋น์ค์์ ๋ณธ์ธ ๋ธ๋ผ์ฐ์ ๋ก ํธ์ ๋ฉ์์ง๋ฅผ ์ ๋ฌํ์ฌ ์๋ฆผ์ด ๋
ธ์ถ๋ ๊ฒ์ด๋ค.
๋ฐ๋ชจ๋ฅผ ํตํด ๋ณธ์ธ์๊ฒ ํธ์ ๋ฉ์์ง๋ฅผ ์ ์กํ๊ฑฐ๋, ๋ค๋ฅธ ์ฌ์ฉ์์๊ฒ ๋ฉ์์ง๋ฅผ ์ ์กํ ์๋ ์๋ค.
๋ค๋ฅธ ์ฌ์ฉ์์๊ฒ ํธ์ ๋ฉ์์ง๋ฅผ ์ ์กํ๋ ๊ณผ์ ์ ์๋ ์์์ ์ฐธ๊ณ ํ๋ฉด ์ข์ ๊ฒ ๊ฐ๋ค.
์ง๊ธ๊น์ง ์น ํธ์์ ๋ํด ์ ๋ฐ์ ์ผ๋ก ์ดํด๋ณด์๋ค.
๋ค์ดํฐ๋ธ์์๋ง ๊ตฌํ ๊ฐ๋ฅํ๋ ํธ์ ์๋ฆผ์ ์น ํ๊ฒฝ์์ ๊ตฌํํ๊ณ , ์ฌ์ฉ์์๊ฒ ๊ธฐ๋ฅ์ ์ ๊ณตํ ์ ์๋ค๋ ์ ์ ์น์ด๋ผ๋ ํ๋ซํผ์ ํฐ ๋ฌด๊ธฐ๋ฅผ ์ฅ์ด์ค ๊ฒ์ด๋ผ๊ณ ์๊ฐํ๋ค.
์ด๋ฒ์ ์์๋ณธ ํธ์ ์๋ฆผ ๋ฟ๋ง ์๋๋ผ ๊ฒฐ์ ์์ฒญ, ์์ฒด ์ธ์ฆ, ํ์ผ ์์คํ
๋ฑ ์ฌ๋ฌ ๊ฐ์ง API ์ฌ์๋ค์ด ํ์ํ๊ณ ๊ตฌํ๋๊ณ ์๋ ๊ฐ์ด๋ฐ, ์์ผ๋ก์ ์น์ด ์ด๋ป๊ฒ ๋ณํํ ์ง ๋์ฑ๋ ๊ถ๊ธํด์ง๋ค.
References