Open seohl16 opened 2 years ago
import { HttpService } from '@nestjs/axios';
import { Injectable } from '@nestjs/common';
import axios from 'axios';
@Injectable()
export class AuthService {
constructor(private readonly httpService: HttpService) {}
async tokenValidation(accessToken: string) {
await axios({
method: 'get',
url: 'https://kapi.kakao.com/v2/user/me',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
}
})
.then((res) => {
console.log(res.data);
})
.catch((err) => {
console.log(err);
})
}
}
service.ts 파일에 tokenValidation이라는 함수를 만든다.
import { Injectable } from "@nestjs/common";
import { PassportStrategy } from "@nestjs/passport";
import { Strategy } from "passport-kakao";
import * as config from 'config';
import { AuthKakaoDto } from "./dto/auth.kakao-dto";
import { AuthService } from "./auth.service";
@Injectable()
export class StrategyKakao extends PassportStrategy(Strategy, 'kakao') {
constructor(public readonly authService: AuthService) {
super({
clientID: config.get('kakao.clientId'),
callbackURL: config.get('kakao.callbackURL'),
});
}
async validate(accessToken: string, refreshToken: string, profile, done) {
const data = await (this.authService.tokenValidation(accessToken));
console.log("accesstoken", accessToken);
const payload: AuthKakaoDto = {
name: profile._json.kakao_account.profile.nickname,
kakaoid: profile._json.id,
};
done(null, payload);
}
}
strategy.ts의 validate 함수를 수정한다. -> await thisService.tokenValidation으로 accessToken을 넘겨서 함수를 수행한다.
console.log(res.data)를 한 결과
{
id: 24234252,
connected_at: '2022-07-30T07:41:17Z',
properties: { nickname: 'se' },
kakao_account: {
profile_nickname_needs_agreement: false,
profile: { nickname: 'se' }
}
}
이 나온다.
profile이용한 Payload가 아니라 유효한 토큰을 통해 검사한 api에서 얻은 정보를 돌려주기로 한다.
import { Injectable } from "@nestjs/common";
import { PassportStrategy } from "@nestjs/passport";
import { Strategy } from "passport-kakao";
import * as config from 'config';
import { AuthKakaoDto } from "./dto/auth.kakao-dto";
import { AuthService } from "./auth.service";
@Injectable()
export class StrategyKakao extends PassportStrategy(Strategy, 'kakao') {
constructor(public readonly authService: AuthService) {
super({
clientID: config.get('kakao.clientId'),
callbackURL: config.get('kakao.callbackURL'),
});
}
async validate(accessToken: string, refreshToken: string, profile, done) {
const user: AuthKakaoDto = await (this.authService.getUserMe(accessToken));
console.log(user);
console.log("accesstoken", accessToken);
done(null, user);
}
}
import { HttpService } from '@nestjs/axios';
import { Injectable } from '@nestjs/common';
import axios from 'axios';
import { AuthKakaoDto } from './dto/auth.kakao-dto';
@Injectable()
export class AuthService {
constructor(private readonly httpService: HttpService) {}
async getUserMe(accessToken: string) : Promise < AuthKakaoDto > {
let user: AuthKakaoDto;
await axios({
method: 'get',
url: 'https://kapi.kakao.com/v2/user/me',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
}
})
.then((res) => {
// 유효한 토큰은 사용자 정보를 돌려준다.
console.log('good');
user = {
name: res.data.kakao_account.profile.nickname,
kakaoid: res.data.id,
};
return user;
})
.catch((err) => {
// 유효하지 않은 토큰은 401에러를 돌려준다.
console.log(err);
})
return user;
}
}
@Injectable()
export class StrategyKakao extends PassportStrategy(Strategy, 'kakao') {
constructor(public readonly authService: AuthService) {
super({
clientID: config.get('kakao.clientId'),
callbackURL: config.get('kakao.callbackURL'),
});
}
async validate(accessToken: string, refreshToken: string, profile, done) {
const user: AuthKakaoDto = await (this.authService.getUserMe(accessToken));
console.log(user);
console.log("accesstoken", accessToken);
const payload = {}
done(null, payload);
}
}
이렇게 payload를 {} 빈 배열로 바꾸고 controller에서 req.user를 어떻게 받는지 확인해보니
{} {
code: 'KW_DHNSbL7j0egnSFfJUP3xm1X_nWDzl0awqwHOPN1k_DYB4xtUPFgbpNYRqwdoAAAGCTl8dFQ'
}
finish
오류는 없는데 user 정보가 하나도 없어진다. payload를 user로 인식하고 있던게 맞았나보다.
Access Token 유효성 검사
Accesstoken의 유효성 검사를 하기 위해서 다양한 방법이 있는데 나느 이 블로그에서 추천하는 방법을 사용했다. kapi.kakao.com/v2/user/me 에 acesstoken을 보내서 유저 정보를 얻을 수 있는 지 확인하는 방법인데, 유효한 토큰이면 200 응답과 정보가 담긴 json을 돌려주고, 만료된 토큰이면 401 응답을 돌려준다.
이걸 검사하기 위해서 우리는
axios
라는 라이브러리 및 함수를 사용하려고 한다.필요한 모듈 설치
그 외 또 참고한 사이트