From 065f1e7c7a1cea78c3a206b1ae709c93cfa7bf9d Mon Sep 17 00:00:00 2001 From: stae1102 Date: Mon, 6 May 2024 19:09:16 +0900 Subject: [PATCH] feat: use appleSignin library --- package-lock.json | 79 ++++++++++++++++++++++++++++++++++++- package.json | 1 + src/auth/oauth.service.ts | 2 +- src/auth/util/oauth.util.ts | 55 ++++++++++---------------- 4 files changed, 99 insertions(+), 38 deletions(-) diff --git a/package-lock.json b/package-lock.json index 80ebbdc..e2e7d1d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,7 @@ "@types/crypto-js": "^4.1.1", "@types/passport-google-oauth20": "^2.0.11", "@types/uuid": "^9.0.0", + "apple-signin-auth": "^1.7.6", "axios": "^0.27.2", "bcrypt": "^5.0.1", "cache-manager": "^4.1.0", @@ -4764,6 +4765,37 @@ "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==" }, + "node_modules/apple-signin-auth": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/apple-signin-auth/-/apple-signin-auth-1.7.6.tgz", + "integrity": "sha512-edXKmteQRbsaxZRvF1mJpbI5UgTvoTnUrdco8+KLiFvOIh/naEB4BYu0xkWZ9+OeFQup1YyvVf5PlaaNAJHpGg==", + "dependencies": { + "jsonwebtoken": "^9.0.0", + "node-fetch": "^2.6.7", + "node-rsa": "^1.1.1" + } + }, + "node_modules/apple-signin-auth/node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, "node_modules/aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", @@ -4888,7 +4920,6 @@ "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, "dependencies": { "safer-buffer": "~2.1.0" } @@ -9642,6 +9673,14 @@ "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", "dev": true }, + "node_modules/node-rsa": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/node-rsa/-/node-rsa-1.1.1.tgz", + "integrity": "sha512-Jd4cvbJMryN21r5HgxQOpMEqv+ooke/korixNNK3mGqfGJmy0M77WDDzo/05969+OkMy3XW1UuZsSmW9KQm7Fw==", + "dependencies": { + "asn1": "^0.2.4" + } + }, "node_modules/nopt": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", @@ -16789,6 +16828,35 @@ "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==" }, + "apple-signin-auth": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/apple-signin-auth/-/apple-signin-auth-1.7.6.tgz", + "integrity": "sha512-edXKmteQRbsaxZRvF1mJpbI5UgTvoTnUrdco8+KLiFvOIh/naEB4BYu0xkWZ9+OeFQup1YyvVf5PlaaNAJHpGg==", + "requires": { + "jsonwebtoken": "^9.0.0", + "node-fetch": "^2.6.7", + "node-rsa": "^1.1.1" + }, + "dependencies": { + "jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "requires": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + } + } + } + }, "aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", @@ -16899,7 +16967,6 @@ "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, "requires": { "safer-buffer": "~2.1.0" } @@ -20520,6 +20587,14 @@ "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", "dev": true }, + "node-rsa": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/node-rsa/-/node-rsa-1.1.1.tgz", + "integrity": "sha512-Jd4cvbJMryN21r5HgxQOpMEqv+ooke/korixNNK3mGqfGJmy0M77WDDzo/05969+OkMy3XW1UuZsSmW9KQm7Fw==", + "requires": { + "asn1": "^0.2.4" + } + }, "nopt": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", diff --git a/package.json b/package.json index 31a979a..5d64b8e 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "@types/crypto-js": "^4.1.1", "@types/passport-google-oauth20": "^2.0.11", "@types/uuid": "^9.0.0", + "apple-signin-auth": "^1.7.6", "axios": "^0.27.2", "bcrypt": "^5.0.1", "cache-manager": "^4.1.0", diff --git a/src/auth/oauth.service.ts b/src/auth/oauth.service.ts index 688ff86..75515bf 100644 --- a/src/auth/oauth.service.ts +++ b/src/auth/oauth.service.ts @@ -183,7 +183,7 @@ export class OAuthService { } public async appleLogin(code: string) { - const { data } = await this.oauthUtil.getAppleToken(code); + const data = await this.oauthUtil.getAppleToken(code); if (!data.id_token) { throw new InternalServerErrorException( diff --git a/src/auth/util/oauth.util.ts b/src/auth/util/oauth.util.ts index 454deb4..bc33aae 100644 --- a/src/auth/util/oauth.util.ts +++ b/src/auth/util/oauth.util.ts @@ -10,11 +10,19 @@ import { GetKakaoUserInfoOutput, } from '../dtos/kakao.dto'; import { JwtService } from '@nestjs/jwt'; +import appleSignin from 'apple-signin-auth'; @Injectable() export class OAuthUtil { constructor(private readonly jwtService: JwtService) {} + private readonly CLIENT_ID = process.env.APPLE_CLIENT_ID; + private readonly TEAM_ID = process.env.APPLE_TEAM_ID; + private readonly PRIMARY_KEY = String(process.env.APPLE_SECRET_KEY) + .split(String.raw`'\n`) + .join('\n'); + private readonly KEY_ID = process.env.APPLE_KEY_ID; + // Get access token from Kakao Auth Server async getKakaoAccessToken(code: string): Promise { try { @@ -72,44 +80,21 @@ export class OAuthUtil { } } - getAppleAccessToken(): string { - const timeNow = Math.floor(Date.now() / 1000); - - const claims = { - iss: process.env.APPLE_TEAM_ID, - iat: timeNow, - aud: 'https://appleid.apple.com', - sub: process.env.APPLE_CLIENT_ID, - }; - - const privateKey = process.env - .APPLE_SECRET_KEY!.split(String.raw`\n`) - .join('\n'); - console.log(privateKey); - - return this.jwtService.sign(claims, { - keyid: process.env.APPLE_KEY_ID, - expiresIn: timeNow + 300, - privateKey, - algorithm: 'ES256', + getClientSecret(): string { + return appleSignin.getClientSecret({ + clientID: this.CLIENT_ID!, + teamID: this.TEAM_ID!, + privateKey: this.PRIMARY_KEY!, + keyIdentifier: this.KEY_ID!, + expAfter: 300, }); } async getAppleToken(code: string) { - return await axios.post( - 'https://appleid.apple.com/auth/token', - qs.stringify({ - grant_type: 'authorization_code', - code, - client_secret: this.getAppleAccessToken(), - client_id: process.env.APPLE_CLIENT_ID, - redirect_uri: process.env.APPLE_REDIRECT_URI, - }), - { - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - }, - ); + return await appleSignin.getAuthorizationToken(code, { + clientID: this.CLIENT_ID!, + redirectUri: process.env.APPLE_REDIRECT_URI!, + clientSecret: this.getClientSecret(), + }); } }