https://kauth.kakao.com/oauth/authorize?scope=account_email&response_type=code&client_id=[REST API key]&redirect_uri=[Redirect URI]
https://accounts.google.com/o/oauth2/v2/auth?scope=https%3A//www.googleapis.com/auth/userinfo.profile%20https%3A//www.googleapis.com/auth/userinfo.email&access_type=offline&include_granted_scopes=true&response_type=code&redirect_uri=[Redirect URI]&client_id=[Client ID]
https://appleid.apple.com/auth/authorize?client_id=[CLIENT_ID]&redirect_uri=[REDIRECT_URL]&response_type=code%20id_token&state=[STATE]&scope=name%20email&response_mode=form_post
https://github.com/youngkiu/nestjs-kakaologin/blob/main/src/auth/google/google.strategy.ts
다른 여타의 passport-oauth2와 다르게, validate()
method를 구현하지 않으며,
(response_type=code%20id_token
이기 때문이며, response_type=code
이면 구현해야 한다.)
다른 여타의 passport-oauth2의 validate()
에서 하는 역할을 constructor의 callback으로 제공한다.
https://github.com/ananay/passport-apple
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { PassportStrategy } from '@nestjs/passport';
import { JwtService } from '@nestjs/jwt';
import { Strategy } from 'passport-apple';
import { PinoLogger } from 'nestjs-pino';
import { readFileSync } from 'fs';
import { AppleUserDataDto } from './apple_user_data.dto';
import { UserService } from '../../user/user.service';
import { CreateUserDto } from '../../user/create_user.dto';
@Injectable()
export class AppleStrategy extends PassportStrategy(Strategy) {
constructor(
private readonly configService: ConfigService,
private readonly jwtService: JwtService,
private readonly userService: UserService,
private readonly logger: PinoLogger,
) {
logger.setContext(AppleStrategy.name);
super(
{
clientID: configService.get<string>('APPLE_CLIENT_ID'),
teamID: configService.get<string>('APPLE_TEAM_ID'),
callbackURL: configService.get<string>('APPLE_CALLBACK_URL'),
keyID: configService.get<string>('APPLE_KEY_ID'),
privateKeyString: readFileSync(
configService.get<string>('APPLE_KEYFILE_PATH'),
),
passReqToCallback: true,
},
async function (req, accessToken, refreshToken, idToken, profile, cb) {
try {
const idTokenDecoded = jwtService.decode(idToken) as AppleUserDataDto;
logger.debug(JSON.stringify(idTokenDecoded));
const provider = 'google';
const { sub: providerId, email } = idTokenDecoded;
const user = await userService.find(provider, providerId);
if (user) {
return cb(null, user);
}
const userData: CreateUserDto = {
provider,
providerId,
email,
profile: idTokenDecoded,
accessToken,
refreshToken,
};
await userService.create(userData);
cb(null, userData);
} catch (error) {
logger.error(error);
}
},
);
}
}
참고)