사용자가 네이버/카카오 로그인 페이지에서 로그인을 진행한다
네이버/카카오에서 콜백 또는 redirect_uri로 인가 코드를 담아 GET 요청을 보낸다
NaverStrategy, KakaoStrategy에서 자동으로 인가 코드를 담아 네이버/카카오 인증 서버에 요청을 보내 액세스 토큰, 리프레시 토큰, 프로필 정보를 응답 받는다.
응답 받은 프로필 정보를 각 Strategy의 validate에서 User에 담아 return한다
Controller에 있는 naverSignIn, kakaoSignIn에서 GetUser를 통해 validate에서 전달된 네이버/카카오 사용자(user)의 정보를 얻는다
Service에 있는 naverSignIn, kakaoSignIn에서 다음의 동작을 수행한다
두 OAuth 로그인을 다음의 과정으로 구현하면 클라이언트 입장에서는 1번에 써있는 요청 하나만으로 로그인 API와 동일한 결과를 얻을 수 있습니다.
소셜 로그인 여부 칼럼의 추가 등 엔티티의 변경이 있어도 Strategy에서 담는 User의 정보에 해당 칼럼 값을 True로 변경만 하면 되고, 추가적으로 일반 사용자에게 해당 칼럼값을 False로 설정만 해주면 됩니다.
import {
Entity,
Column,
PrimaryGeneratedColumn,
CreateDateColumn,
UpdateDateColumn,
DeleteDateColumn,
BaseEntity,
OneToMany,
Unique,
} from "typeorm";
import { premiumStatus, providerEnum } from "src/utils/enum";
import { Diary } from "../diaries/diaries.entity";
import { Shape } from "src/shapes/shapes.entity";
@Entity()
@Unique(["userId"])
export class User extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;
@Column({ length: 60 })
userId: string;
@Column()
email: string;
@Column({ length: 60 })
password: string;
@Column({ length: 20 })
nickname: string;
@Column({ default: 0 })
credit: number;
@Column({ type: "enum", enum: premiumStatus, default: premiumStatus.FALSE })
premium: premiumStatus;
@CreateDateColumn({ type: "datetime" })
createdDate: Date;
@UpdateDateColumn({ type: "datetime" })
updatedDate: Date;
@DeleteDateColumn({ type: "datetime" })
deletedDate: Date;
@Column({ type: "enum", enum: providerEnum, default: providerEnum.BYEOLSOOP })
provider: providerEnum;
@OneToMany(() => Diary, (diary) => diary.user)
diaries: Diary[];
@OneToMany(() => Shape, (shape) => shape.user)
shapes: Diary[];
}