[Node.js] 카카오 로그인&JWT
2021. 9. 17. 16:49ㆍWeb_Programming/Node.js
이전에 [리액트_ts를 이용하여, 카카오 로그인 구현]에 대해 포스팅했습니다.
이번에는 서버 측에서 처리한 카카오 로그인 구현에 대해 작성해볼게요 :-D
카카오 로그인 구현
토큰을 이용한 로그인의 전체적인 흐름은 다음과 같습니다.
- 로그인 → 인가 코드 발급
client
- 인가 코드 → 토큰 발급(access, refresh)
client
- access토큰을 서버로 넘겨 사용자 인증 후 DB 저장 → JWT 토큰 발급
server
- JWT 토큰 localStorage에 저장 후, 자동 로그인 처리
client
서버 파트는 여기서 3번의 로직을 처리하게 됩니다
Get Profile
access 토큰을 이용하여 카카오로부터 User 정보 받기
저는 프로필 정보를 받는 getProfile promise를 따로 파일에 생성해뒀습니다.
const request = require('request');
module.exports = {
getProfile(accessToken) {
return new Promise((resolve, reject) => {
request(
{
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',
},
url: 'https://kapi.kakao.com/v2/user/me',
method: 'GET',
},
(error, response, body) => {
if (!error && response.statusCode === 200) {
resolve(body);
}
reject(error);
}
);
});
},
User 정보 받기
카카오 로그인을 이용한 초기 로그인의 경우,
위에서 언급한 getProfile에 프론트로부터 받은 카카오 access_token을 넘겨 User 정보를 카카오로부터 받습니다.
자동 로그인의 경우는 프론트에서 header로 넘긴 JWT 토큰을 통해 User 정보를 받습니다.
(JWT 인증방법은 하단에서 설명)
const express = require('express');
const kakaoAuth = require('../utils/KakaoAuth');
const router = express.Router();
router.post('/kakao', async (req, res) => {
try{
let userEmail = "";
let userNickName = "";
if (req.body.access_token) {
//초기 로그인
const result = await kakaoAuth.getProfile(req.body.access_token);
const kakaoUser = JSON.parse(result).kakao_account;
userEmail = kakaoUser.email;
userNickName = kakaoUser.profile.nickname;
} else {
//자동 로그인
const user = jwt.verify(req.headers.authorization, process.env.JWT_SECRET, {
ignoreExpiration: true,
});
userEmail = user.email;
}
} catch (err) {
return res.status(500).json({
success: false,
error: err.toString(),
});
}
});
User 정보 create or find
위에서 받은 user 식별 정보 (email)를 이용하여
if DB에 User정보가 있다면 → find
else → create 하여 계정을 생성해줍니다.
const [user, created] = await User.findOrCreate({
where: { email: userEmail },
defaults: {
socialType: 'kakao',
nickName: userNickName,
kakaoToken: req.body.access_token
},
attributes: ['id', 'nickName'],
});
let responseData = {
success: true,
user,
};
JWT 토큰 생성
초기 로그인의 경우 JWT 토큰을 프론트로 넘겨줘야 하기 때문에,
jwt.sign을 통해 JWT 토큰을 발급하여 res.json으로 넘겨줍니다.
if (req.body.access_token) {
const token = jwt.sign({
id: user.id,
email: userEmail,
}, process.env.JWT_SECRET, {
issuer: 'bbangsoon',
});
responseData.jwt = token;
}
return res.status(created? 201: 200).json(responseData);
이렇게 jwt토큰과 user 정보를 넘기면
서버에서의 카카오 로그인 구현 끝입니다
+ 쿠키 기반 인증 로직을 사용하는 경우, json이 아닌 cookie에 설정해주면 됩니다.
/auth 전체 코드
const express = require('express');
const jwt = require('jsonwebtoken');
const { User } = require('../models');
const kakaoAuth = require('../utils/KakaoAuth');
const router = express.Router();
router.post('/kakao', async (req, res) => {
try{
let userEmail = "";
let userNickName = "";
if (req.body.access_token) {
//초기 로그인
const result = await kakaoAuth.getProfile(req.body.access_token);
const kakaoUser = JSON.parse(result).kakao_account;
userEmail = kakaoUser.email;
userNickName = kakaoUser.profile.nickname;
} else {
//자동 로그인
const user = jwt.verify(req.headers.authorization, process.env.JWT_SECRET, {
ignoreExpiration: true,
});
userEmail = user.email;
}
const [user, created] = await User.findOrCreate({
where: { email: userEmail },
defaults: {
socialType: 'kakao',
nickName: userNickName,
kakaoToken: req.body.access_token
},
attributes: ['id', 'nickName'],
});
let responseData = {
success: true,
user,
};
if (req.body.access_token) {
const token = jwt.sign({
id: user.id,
email: userEmail,
}, process.env.JWT_SECRET, {
issuer: 'bbangsoon',
});
responseData.jwt = token;
}
return res.status(created? 201: 200).json(responseData);
} catch (err) {
return res.status(500).json({
success: false,
error: err.toString(),
});
}
});
JWT 인증 방법
패키지 설치
npm i jsonwebtoken
.env 파일에 JWT_SCERET으로 설정하고자 하는 secret key 값을 지정합니다.
jwt.sign
: 계정 생성
first_param : 계정 정보
second_param : 설정한 secret key
const token = jwt.sign({
id: user.id,
email: userEmail,
}, process.env.JWT_SECRET, {
issuer: 'bbangsoon',
});
jwt.verify
: 사용자 인증
first_param : JWT 토큰
second_param : 설정한 secret key
const user = jwt.verify(access_token, process.env.JWT_SECRET, {
ignoreExpiration: true,
});
'Web_Programming > Node.js' 카테고리의 다른 글
[Node.js] NCP SENS 문자 발송 API (4) | 2021.05.29 |
---|