framework/NextAuth

๐Ÿ Apple OAuth Provider ๊ฐœ์š”

octo54 2025. 5. 8. 11:15
๋ฐ˜์‘ํ˜•

 

๐Ÿ Apple OAuth Provider ๊ฐœ์š”

Apple OAuth๋Š” OAuth 2.0 ๋ฐ OpenID Connect๋ฅผ ์ง€์›ํ•˜๋ฉฐ,
Apple ID๋ฅผ ํ†ตํ•ด ๊ฐ„ํŽธํ•˜๊ฒŒ ์ธ์ฆํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ› ๏ธ ์„ค์ • ์˜ˆ์‹œ (pages/api/auth/[...nextauth].ts)

import NextAuth from "next-auth"
import AppleProvider from "next-auth/providers/apple"

export default NextAuth({
  providers: [
    AppleProvider({
      clientId: process.env.APPLE_CLIENT_ID,
      clientSecret: process.env.APPLE_CLIENT_SECRET,
    }),
  ],
})

๐Ÿ“‘ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ • (.env)

APPLE_CLIENT_ID=com.example.app
APPLE_CLIENT_SECRET=your-apple-client-secret
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your-nextauth-secret

๐Ÿ Apple Developer ๊ณ„์ • ์„ค์ •

  1. Apple Developer ๊ณ„์ •์— ๋กœ๊ทธ์ธ
  2. IdentifiersServices IDs → ์ƒˆ๋กœ์šด ์„œ๋น„์Šค ID ์ƒ์„ฑ
  3. Redirect URI:
  4. https://localhost:3000/api/auth/callback/apple
  5. Key ์ƒ์„ฑ:
    • Apple ํ‚ค ID๋ฅผ ๋ฐœ๊ธ‰๋ฐ›์•„์•ผ ํ•จ
    • ํŒ€ ID๋„ ํ•„์š”

๐Ÿ” Apple Private Key ์ƒ์„ฑ

๋ฐ˜์‘ํ˜•
  1. Apple Developer Console์—์„œ ํ‚ค ์ƒ์„ฑ
  2. ์ƒ์„ฑ๋œ .p8 ํ‚ค ํŒŒ์ผ์„ ํ”„๋กœ์ ํŠธ์— ์ถ”๊ฐ€
  3. ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ •:
  4. APPLE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMIIEv...\n-----END PRIVATE KEY-----" APPLE_KEY_ID=ABC123DEFG APPLE_TEAM_ID=TEAM123456

๐Ÿ“‚ Apple ํด๋ผ์ด์–ธํŠธ ์‹œํฌ๋ฆฟ ์ƒ์„ฑ ํ•จ์ˆ˜

Apple OAuth์—์„œ๋Š” JWT ํ† ํฐ์„ ํด๋ผ์ด์–ธํŠธ ์‹œํฌ๋ฆฟ์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
๋‹ค์Œ๊ณผ ๊ฐ™์€ ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ JWT๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค:

import jwt from "jsonwebtoken"

function generateAppleSecret() {
  return jwt.sign(
    {
      iss: process.env.APPLE_TEAM_ID,
      aud: "https://appleid.apple.com",
      sub: process.env.APPLE_CLIENT_ID,
    },
    process.env.APPLE_PRIVATE_KEY.replace(/\\n/g, '\n'),
    {
      algorithm: "ES256",
      expiresIn: "1h",
      keyid: process.env.APPLE_KEY_ID,
    }
  )
}

๐Ÿ”„ Apple OAuth ์ฝœ๋ฐฑ ์„ค์ •

async function jwt({ token, account }) {
  if (account?.provider === "apple") {
    token.idToken = account.id_token
  }
  return token
}

โš ๏ธ ์ฃผ์˜์‚ฌํ•ญ

  • Apple OAuth๋Š” ๋น„๋ฐ€๋ฒˆํ˜ธ ๋Œ€์‹  ์ƒ์ฒด ์ธ์‹(Face ID/Touch ID)์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
  • id_token์„ ์‚ฌ์šฉํ•ด ์‚ฌ์šฉ์ž์˜ ์ด๋ฆ„๊ณผ ์ด๋ฉ”์ผ์„ ๊ฐ€์ ธ์™€์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    ์ดˆ๊ธฐ ๋กœ๊ทธ์ธ ์‹œ ํ•œ ๋ฒˆ๋งŒ ์ œ๊ณต๋˜๋ฏ€๋กœ ๋ฐ˜๋“œ์‹œ ์ €์žฅํ•ด๋‘์„ธ์š”.

 

NextAuth Apple OAuth, Apple ๋กœ๊ทธ์ธ ๊ตฌํ˜„, OAuth2 Next.js, Apple ID ์ธ์ฆ ์„ค์ •, Apple Private Key ์‚ฌ์šฉ๋ฒ•, JWT ํ† ํฐ ์ƒ์„ฑ, OAuth ์ฝœ๋ฐฑ ์ฒ˜๋ฆฌ, Next.js ๋กœ๊ทธ์ธ ๊ตฌ์„ฑ, Apple ํ‚ค ์„ค์ •, SEO ์ตœ์ ํ™” 10๊ฐœ