지난 금요일까지 만든 kakao login은 session에 카카오만 들어가 있는 상태↓
req.session.kakao=user.data;
kakao, naver, google, local server 등등.. 많은 로그인 기능을 연결하려면 각각 사이트마다 주는 결과도 다르기 때문에 하나에 모아서 처리할 예정
1. session에 웹사이트별 구분 속성값 만들어 넣기
server.js
const authData = { //authData 변수에 token.data, user.data 값을 객체로 담음
...token.data,
...user.data,
}
req.session.authData = { //session 안에 kakao라는 속성에 authData의 객체값들을 넣음
["kakao"]:authData,
}
console.log(req.session);
res.redirect('/');
});
- authData 라는 변수에 axios로 받아온 결과를 담은 token, user 의 data 값을 비구조 할당문을 이용해서 담음
- session에 authData라는 속성을 만들어서 안에 ["kakao"] : authData 변수 값을 객체로 담음
console.log(req.session) 을 찍어보면
Session {
cookie: { path: '/', _expires: null, originalMaxAge: null, httpOnly: true },
authData: {
kakao: {
access_token: 'CphfrW0WX4zEj8KojpNYhQg',
token_type: 'bearer',
refresh_token: '6wHaQCXwHlAHgcQkvYhQg',
expires_in: 21599,
scope: 'account_email profile',
refresh_token_expires_in: 599,
id: 17392,
connected_at: '2021-05-21T02:27:37Z',
properties: [Object],
kakao_account: [Object]
}
}
}
session cookie 존재
속성 추가한 authData 안 kakao라는 속성값으로 ...token.data, ...user.data 들이 쭉 - 들어가 있음
req.session... 계속 이렇게 쓰기 복잡하니 간단하게 바꾸기
req.session => session / req.query => query / req.query.code => code
app.get('/auth/kakao/callback', async (req, res) => {
let {session,query} = req; // 추가 1 req안 session, query란 객체가 있는데 저 변수에 담는다.
let {code} = query; // 추가 2 req.query 안 code라는 객체를 담음
let token;
try {
token = await axios({
method: 'POST',
url: 'https://kauth.kakao.com/oauth/token',
headers: {
'content-type': 'application/x-www-form-urlencoded'
},
data: qs.stringify({
grant_type: 'authorization_code',
// 특정 string 넣기
client_id: kakao.clientID,
client_secret: kakao.clientSecret,
redirectUri: kakao.redirectUri,
code, //code: req.query.code, //변경 1
//auth/kakao/callback일때 get값으로 준 코드야
})
//객체를 string으로 변환
})
} catch (err) {
res.json(err.data)
}
//kakao에게 요청 /
let user;
try{
user = await axios({
method:"GET",
url:'https://kapi.kakao.com/v2/user/me',
headers:{
Authorization:`Bearer ${token.data.access_token}`
}
})
}catch(err){
res.json(err.data)
}
const authData = {
...token.data,
...user.data,
}
session.authData = { // req.session -> session 변경 2
["kakao"]:authData,
}
console.log(session);
res.redirect('/');
});
비구조 할당문이란?
2. /auth/info & info.html 수정
server.js
app.get('/auth/info',(req,res)=>{
const provider = Object.keys(req.session.authData)[0]; //or req.session.authData.kakao
console.log(provider) //kakao찍힘
res.render('info.html');
})
Object.keys() -> 해당 객체의 key값 / 속성이름 (여기서는'kakao') 만 가져옴
switch 문으로 만약 provider 변수의 내용이 kakao라면 ~ 아래 userinfo={ useid에 kakao 값을 넣겠다.}
app.get('/auth/info',(req,res)=>{
const provider = Object.keys(req.session.authData)[0];
console.log(provider)
let userinfo = {}
switch (provider){
case 'kakao' :
userinfo = {
userid:req.session.authData[provider].properties.nickname,
}
break;
}
res.render('info.html',{
userinfo,
});
})
info.html
당신의 id는 {{userinfo.userid}}입니다.
server on -> check
server.js /auth/info 부분도 authData객체를 변수에 담아 코드 줄이기
app.get('/auth/info',(req,res)=>{
const {authData} = req.session;
const provider = Object.keys(authData)[0];
let userinfo = {}
switch (provider){
case 'kakao' :
userinfo = {
userid:authData[provider].properties.nickname,
}
break;
}
res.render('info.html',{
userinfo,
});
})
3. 로그인 여부 체크
middleware 하나 만들어서 /auth/info 로 들어올 때 한번 거치도록 만들기
const authMiddleware = (req,res,next)=>{ // middleware 만듬 -> session.authData가 없으면
const {session} = req;
if(session.authData==undefined){
console.log('로그인 안되어 있음 '); // 요거 출력
res.redirect('/?msg=로그인 안되어 있습니다.');
}else{
console.log('로그인 되어 있음 '); //되어 있으면 next() - 계속가 ~
next();
}
}
app.get('/auth/info',authMiddleware, (req,res)=>{ //(req,res) 전 middleware 입력
const {authData} = req.session;
auth/info 들어오면 authMiddleware 로 감 -> authMiddleware 변수에 담긴 익명 함수 거쳐서
로그인이 안된경우 redirect -> 이 때 get값으로 msg = 로그인 안되어있습니다. 를 줌 -> 나중에 msg를 사용할 예정
로그인 된 경우 next() -> /auth/info 아래쪽 다 실행
4. 카카오 회원 탈퇴 by data
views - index.html 탈퇴 버튼 추가
<a href="/auth/kakao">카카오 로그인</a>
<a href="/auth/info">회원정보</a>
<a href = "/auth/kakao/unlink">카카오 탈퇴 </a>
server.js
app.get('/auth/kakao/unlink',async (req,res)=>{
const {session} = req;
const {access_token} = session.authData.kakao;
console.log(access_token); //출력 결과 : djsklcenfaseyr8w3hrkejsdfh74
let unlink;
try{
unlink = await axios({
method:'POST',
url:'https://kapi.kakao.com/v1/user/unlink',
headers:{
Authorization:`Bearer ${access_token}`
}
})
}catch(err){
res.json(err.data);
}
console.log(unlink.data); //출력 결과 : {id : 249856349524}
})
<- 아까 token.data, user.data를 담아 둔 authData 변수 안에 kakao라는 속성값으로 내용들을 넣어둠
요걸 사용해서 access_token 값을 headers에 안보이게 잘 보내서 회원 탈퇴 요청
console.log(unlink.data)에 찍힌 id 값을 사용 = 요 값은 카카오쪽에 요청보내서 받은 값
-> 이제 요 값이 local server session에 저장한 id값과 같으면 session에서 삭제
app.get('/auth/kakao/unlink',async (req,res)=>{
const {session} = req;
const {access_token} = session.authData.kakao;
console.log(access_token);
let unlink;
try{
unlink = await axios({
method:'POST',
url:'https://kapi.kakao.com/v1/user/unlink',
headers:{
Authorization:`Bearer ${access_token}`
}
})
}catch(err){
res.json(err.data);
}
console.log(unlink.data);
const {id} = unlink.data;
if(session.authData['kakao'].id==id){
delete session.authData;
}
res.redirect('/?msg=로그아웃 되었습니다');
})
server on -> check - 회원 탈퇴는 되지만 아직 msg = 로그아웃 되었습니다. 부분이 안나옴
5. msg get값으로 보낸거 alert 만들기
server.js ('/', ()=>{}) 부분에 get값 받는 변수 설정, render 에 함께 보내기
app.get('/', (req, res) => {
const {msg} = req.query;
res.render('index.html',{
msg,
});
})
views- index.html
<a href="/auth/kakao">카카오 로그인</a>
<a href="/auth/info">회원정보</a>
<a href = "/auth/kakao/unlink">카카오 탈퇴 </a>
{% if msg %}
<script type = "text/javascript">
alert ("{{msg}}")
</script>
{% endif %}
server on -> check -> 카카오 탈퇴 후 '로그아웃 되었습니다' alert 뜸. 그리고 로그인안하고 회원정보 보기 볼 때 도 get값으로 msg 넘긴 '로그인이 안되어 있습니다' alert 도 뜸. msg 라는 key로 맞추고, ('/') 을 다 향하게 해서 훨씬 수월해짐
카카오톡 비로그인 상태에서 카카오 탈퇴를 누르면 msg 가 뜨도록 아까 만든 middleWare를
/auth/kakao/unlink 쪽에도 넣기
app.get('/auth/kakao/unlink', authMiddleware, async (req,res)=>{
6. local login 만들기
views - index.html
/login a 링크 버튼 추가
<a href="/auth/kakao">카카오 로그인</a>
<a href="/login">로그인</a>
<a href="/auth/info">회원정보</a>
<a href = "/auth/kakao/unlink">카카오 탈퇴 </a>
{% if msg %}
<script type = "text/javascript">
alert ("{{msg}}")
</script>
{% endif %}
server.js
/login get 추가
app.get('/login',(req,res)=>{
res.render('login.html');
})
views - login.html 생성 / 코드 작성
<form method="post" action="/login">
<input type="text" name="userid">
<input type="password" name="userpw">
<input type="submit" value="로그인">
</form>
Post 사용 - > body-parser 설치 및 코드 작성
$npm install body-parser
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended:false}));
server.js /login post 부분 작성 (db 처리 되었다고 가정)
app.post('/login', (req,res)=>{
const {session,body} = req;
const {userid,userpw} = body;
if(userid=='root' && userpw =='root'){
const data = {
userid,
}
session.authData={
["local"]:data,
}
res.redirect('/?msg=로그인 되었습니다.');
}else{
res.redirect('/?msg=아이디와 패스워드를 확인해주세요');
}
})
local 로 로그인 시 '회원정보' 나오게 수정하기
server.js /auth/info
app.get('/auth/info',authMiddleware, (req,res)=>{
const {authData} = req.session;
const provider = Object.keys(authData)[0];
let userinfo = {}
switch (provider){
case 'kakao' :
userinfo = {
userid:authData[provider].properties.nickname,
}
break;
case 'local' :
userinfo={
userid:authData[provider].userid,
}
break;
}
res.render('info.html',{
userinfo,
});
})
local login 로그아웃 만들기 - 하나의 버튼으로 둘다 로그아웃 가능하게 만들기
index.html logout 버튼 추가 / 카카오탈퇴 버튼 주석
{% if loginInfo==undefined %}
<a href="/auth/kakao">카카오 로그인</a>
<a href="/login">로그인</a>
{% else %}
<a href="/auth/info">회원정보</a>
<a href="/auth/logout"> 로그아웃 </a>
<!--<a href = "/auth/kakao/unlink">카카오 탈퇴 </a>-->
{% endif %}
{% if msg %}
<script type = "text/javascript">
alert ("{{msg}}")
</script>
{% endif %}
server.js /auth/logout 만들기 (kakao, local 로그인인지 구분해서)
server.js
app.get('/auth/logout', (req,res)=>{
const {session} = req;
const {authData} = session;
const provider = Object.keys(authData)[0];
switch(provider){
case 'local' :
delete session.authData;
res.redirect('/?msg=로그아웃 되었습니다.');
break;
case 'kakao' :
res.redirect('/auth/kakao/unlink');
break;
}
})
server on -> check
7. 로그인했을 때, 안했을 때 (session 값이 있을 때, 없을 때) 보이는 버튼 구분하기
server.js
app.get('/', (req, res) => {
const {msg} = req.query;
res.render('index.html',{
msg,
loginInfo:req.session.authData, // 추가
});
})
카카오 로그인 -> local 로그인 하면 login 이 덮어 씌여짐 이 경우 따로따로 코드 작성을 하는게 좋지만 시간 여유없으면 둘 중 하나로 로그인 시 다시 로그인 버튼 안보이게 만들면 됨
index.html
{% if loginInfo==undefined %}
<a href="/auth/kakao">카카오 로그인</a>
<a href="/login">로그인</a>
{% else %}
<a href="/auth/info">회원정보</a>
<a href = "/auth/kakao/unlink">카카오 탈퇴 </a>
{% endif %}
{% if msg %}
<script type = "text/javascript">
alert ("{{msg}}")
</script>
{% endif %}
server on -> check
'블록체인 기반 핀테크 및 응용 SW개발자 양성과정 일기' 카테고리의 다른 글
[50일차 복습] HTTP protocol 구조 개요와 예제 (1) | 2021.05.26 |
---|---|
[50일차] 20210525 HTTP post, get 공부 (0) | 2021.05.26 |
[49일차] 20210524 javaScript 카카오 oauth 로그인 kakao login (1) | 2021.05.25 |
[48일차 복습] JavaScript, node.js, Oauth 로 카카오 로그인 연결해보기 kakao login (0) | 2021.05.24 |
[48일차] 20210521 KAKAO Login Javascript node.js express 카카오 로그인 연결하기 (2) | 2021.05.21 |