참고 문헌
- [소셜로그인] 네이버 로그인 구현하기 node js
1. 네이버 로그인
2. ‘네이버 개발자 센터’ 이동.
3. Application \ 어플리케이션 등록
애플리케이션 이름 : nodejs_naverlogin_api
사용 API : 네이버 로그인
* 네이버에서 제공해줄 네이버 계정의 정보를 선택
회원이름 : 필수
연락처 이메일 주소 : 필수
휴대전화번호 : 필수
로그인 오픈 API
서비스 환경 : PC 웹
서비스URL : http://127.0.0.1:3005/naverlogin
네이버 로그인 Callback URL (최대 5개) : http://127.0.0.1:3005/callback
* 서비스URL : [개발가이드 2.2.5 네이버 로그인 뱃지] 표시 보이게도 해줌.
* 3000, 3001 상관없다. 다만 nodejs 라우터 포트 설정과 동일해야함.
서비스 이용 동의 2개 체크
[등록하기]
그럼 어플리케이션은 세팅 완료.
[nodejs_naverlogin_api]
개요
어플리케이션 정보
Client ID : 678MsYv123O1hzj1o789 // 임의 ID
Client Secret : R12tUEh234 // 임의 Secret
1. 'nodejs_naverlogin' 경로 생성
2. VS Code Open Folder… 'nodejs_naverlogin'
3. VS Code Terminal 열기
4. Node.js module 설치
nodejs_naverlogin> $ npm init -y
nodejs_naverlogin> $ npm i express nodemon babel node-fetch@2
-- 권한 때문에 안되면
nodejs_naverlogin> $ sudo npm i express nodemon babel node-fetch@2
5. npm run 할 때마다 파일명을 입력하지 않게 package.json에 script 설정 추가
"scripts": {
"dev2": "nodemon --exec babel-node 2_Nlogin_accessToken.js",
"dev3": "nodemon --exec babel-node 3_Nlogin_Final.js",
2_파일 소스는 '토큰' 가져오는걸 성공해서 브라우저에 출력하는 것까지,
3_파일 소스는 '토큰' 가져와서, 그 '토큰'을 갖고 다시 '개인정보' 가져오는 것까지
분리해서 확인하기 위함.
(개인적으로는 1_Nlogin_sample.js 파일엔 네이버가 올려준 샘플 소스 보고 계속 비교했다.)
6. 2_Nlogin_accessToken.js 파일 생성
(1) module 가져오고 express 기능 사용을 위한 app 객체 생성.
const express = require("express");
const fetch = require("node-fetch");
var app = express();
(2) login에 필요한 데이터 세팅.
(라우터 안에 반복해서 써도 되지만 반복해서 사용하는 데이터는 가장 바깥의 전역global 변수로 빼두기도 한다.)
var client_id = "678MsYv123O1hzj1o789"; // 임의 id
var client_secret = "R12tUEh234"; // 임의 secret
var redirectURI = encodeURI("http://127.0.0.1:3005/callback"); // 라우터 안에 작성해도 됨.
var state = "RAMDOM_STATE";
var api_url = "";
const PORT = 3005; // app.listen이나 라우터에 반복해서 작성해도 된다.
(3) 어플리케이션 서비스 URL이 요청되면 받을 app.get 라우터 소스 생성
명세를 보면
요청 URL에
작성해야하는 변수들이 적혀있다. 필수 변수 4개.
response_type = code가 기본값.
client_id = 내 어플리케이션의 id
redirect_uri = callback url ( 내 어플리케이션 callback에 적었던 주소 )
state = 샘플 소스에 있는 그대로 사용
api_url = '인증' 요청URL + 위에 작성해둔 변수들을 조합. url 뒤에 파라미터 추가는 ?key=value&key&value 한다.
res.writeHead(200, = 응답이 성공하면 Head에 { } 를 작성한다.
res.end( 인증하러 가는 주소를 가진 a 태그 ) 를 보여준다.
app.get("/naverlogin", function (req, res) {
api_url =
"https://nid.naver.com/oauth2.0/authorize?"
+ "response_type=code"
+ "&client_id=" + client_id
+ "&redirect_uri=" + redirectURI
+ "&state=" + state;
res.writeHead(200, { "Content-Type": "text/html;charset=utf-8" });
res.end(
"<a href='" +
api_url +
"'><img height='50' src='http://static.nid.naver.com/oauth/small_g_in.PNG'/></a>"
);
});
► VS Code - Terminal
nodejs_naverlogin> $ npm run dev2
► 크롬 브라우저 127.0.0.1:3005/naverlogin 요청
* localhost /naverlogin에선 뜨지만, /callback에서 안되니까 쓰지 않기!
아마 네이버 어플리케이션 URL에 127.0.0.1로 적어서 그런 것 같다.
저 버튼을 누른다.
(1) 로긴 안되어있으면, 네이버 로그인 화면이 보이고 사용자는 로긴해야만 '동의' 화면이 보인다.
(2) 로긴 되어있으면, 바로 '동의' 구하는 화면이 바로 보일 것이다.
로그인부터 동의 화면까지는 네이버가 알아서 해놓은 것이니 우리 쪽에선 신경 안 쓴다.
로그인한 사용자가 '동의'까지 했다면,
네이버 쪽에서 콜백으로 로그인한 사용자의 인증 토큰을 보내줌. (네이버 : 로그인한 사람, 인증 끝났어. 이 사람 토큰 줄게)
그러면 우리 쪽에선 그 콜백을 받을 라우터를 세팅하면 된다. (우리 : OK. 사용자 토큰 받을 준비 가요.)
7. 어플리케이션 네이버 로그인 Callback URL이 요청되면 받을 app.get 라우터 소스 생성
* 네이버가 명세 위에 친절하게 적어준 각 언어별 Sample 소스 중 Node.js 소스에는
더이상 사용하지 않는 deprecated된 module 'request'가 있어서
다른 module 'node-fetch@2'를 사용한다.
명세를 보면 (아까는 '인증 요청'하기 위한 a 태그와 app.get(/naverlogin) 라우터만 생성)
이번 콜백엔 token을 json 형태로 발급 받아야한다. ( 아까 요청url 의 oauth2.0/ 뒤의 주소가 다르다.)
url token 뒤에 붙는 변수명은 상황에 따라 다르다.
우리는 '발급' 받아야하니까 기본 3개 + code, state를 사용한다.
(로그아웃 땐 '삭제'가 필수려나)
우리도 요청url에 필요한 데이터를 ? & 형태로 파라미터에 담아 넘겨줬듯이
인증이 성공하면 네이버 쪽에서도 돌려주는 url에 '님 인증됐음' 같은 코드를 파라미터에 담아서 보내준다.
아래 사진 url 속 ?code=e4~& 와 같이 그 code를 말한다. 대신 인증 성공했을 경우만!
req요청한 곳에서 uri ?로 넘겨준 query.code, state를 받는다.
nodejs 문법에선 req.query(url에서 ?key=value&를 query로 가져옴).code(그 중 key가 code)로 가져온다.
이번엔 우리가 네이버에 token 받는걸 요청하고, 성공하면 token값을 브라우저에 출력해본다.
api_url = 'token' 요청 URL + 위에 작성해둔 변수들 조합.
app.get("/callback", async function (req, res) {
const code = req.query.code;
const state = req.query.state;
const api_url =
"https://nid.naver.com/oauth2.0/token?"
+ "grant_type=authorization_code"
+ "&client_id=" + client_id
+ "&client_secret=" + client_secret
+ "&code=" + code
+ "&state=" + state;
// deprecated된 module
/**
var request = require("request");
var options = {
url: api_url,
headers: {
"X-Naver-Client-Id": client_id,
"X-Naver-Client-Secret": client_secret,
},
};
request.get(options, function (error, response, body) {
if (!error && response.statusCode == 200) {
res.writeHead(200, { "Content-Type": "text/json;charset=utf-8" });
res.end(body);
console.log("body", body);
} else {
res.status(response.statusCode).end();
console.log("error = " + response.statusCode);
}
});
*/
const response = await fetch(api_url, {
headers: {
"X-Naver-Client-Id": client_id,
"X-Naver-Client-Secret": client_secret,
},
});
const tokenRequest = await response.json();
return res.send(tokenRequest);
});
token을 발급해달라고 request할 module을 못 쓰니 기존 Sample 소스는 주석하고
fetch로 (api_url에, header '내 어플리케이션 정보')를 보내서
api_url에서 돌아올 응답(token)을 response에 담게 하는 소스를 작성한다.
그 쪽 응답(token)을 json화 해서 tokenRequest에 담는다.
우리 쪽(127.0.0.1:3005/callback)에서는 이 쪽 브라우저에
저 쪽 응답(token)을 보여주는 응답을 한다.
► 크롬 브라우저 127.0.0.1:3005/naverlogin 요청
[/naverlogin] 화면의 '로그인'을 누르면
* 로그인 되어 있을 경우
* 로그인 안 되어 있을 경우
► 크롬 브라우저 - 개인정보 제공에 '동의'하면
app.get("/callback", 라우터 마지막에
return res.send( tokenRequest ); 했던, tokenRequest가 출력된다.
이제 저 access_token을 가지고
'동의'한 사용자의 개인정보를 받는다.
refresh_token은 명세에서 '갱신' 때 필요하다고 했으니 그 때 사용.
token 받아왔으니
개발 가이드 [3.4.4 접근 토큰 발급 요청] 까지 완료했다.
[3.4.5 접근 토큰을 이용하여 프로필 API 호출하기] 진행해서 개인정보를 받으면 된다.
token 가져오던 소스와 비교하기 위해서
3_Nlogin_Final.js 파일을 생성하고 2_파일 소스 전체를 copy한다.
package.json에서 script 설정을 줬기 때문에 3_파일 Run은 npm run dev3 하면 된다.
8. 접근 토큰을 이용하여 프로필 API 호출
3_Nlogin_Final.js 의 app.get("/callback") 라우터 마지막에 tokenRequest부터 수정한다.
const tokenRequest = await response.json();
return res.send(tokenRequest);
아까 fetch로 url 에 header data를 담아 보낸 것처럼
1번 더 fetch로 프로필API url에 header token data를 담아 보낸다.
const tokenRequest = await response.json();
//3단계: access_token으로 사용자 정보 받아오기
if ("access_token" in tokenRequest) {
const { access_token } = tokenRequest;
const apiUrl = "https://openapi.naver.com/v1/nid/me";
const data = await fetch(apiUrl, {
headers: {
Authorization: `Bearer ${access_token}`,
},
});
const userData = await data.json();
console.log("userData:", userData);
}
return res.send("프로필 API 출력");
});
► 크롬 브라우저 127.0.0.1:3005/naverlogin 요청
[/naverlogin] 화면의 '로그인'을 누르면
이렇게 OAuth로 로그인 성공!
'─── Toy Project > Open API, API, 공공데이터' 카테고리의 다른 글
[nodejs] SGIS 단계별 주소 조회 (0) | 2024.10.04 |
---|