[Node.js 찍먹하기] Chapter 05 : 백엔드, 로그인 인증 기능 만들기
33599 단어 Node.js 찍먹하기Node.js 찍먹하기
프론트 엔드에 입력한 데이터를 이용해 인증을 받자
인증과 인가를 받을려면 어떻게 해야할까
🔙 백엔드에서
기존에 인증 받은 데이터들 === 프론트 엔드에서 입력한 데이터
**const user = { // 프론트엔드에서 입력한 정보로, 해당 사용자의 인증, 인가를 해야함 그리기 위해선 인증 받은 데이터들이 있어야한다(이 데이터랑 프론트 엔드 데이터랑 비교해야함)
id: ["양상우", "김개발", "박부장"],
password: ["1234", "1234", "123456"]
}**
- 이렇게 일단 기존 데이터를 명시를 해주고(사실 이렇게 같은 코드에 있으면 절대 안된다)
- POST로 들어온 프론트 엔드에서 입력한 데이터를 비교하는 API를 만들자
"use strict"
const output = {
home: (req, res) => {
res.render("./home/index") // views는 지정했기땨문
},
login: (req, res) => {
res.render("./home/login")
}
}
const user = { // 프론트엔드에서 입력한 정보로, 해당 사용자의 인증, 인가를 해야함 그리기 위해선 인증 받은 데이터들이 있어야한다(이 데이터랑 프론트 엔드 데이터랑 비교해야함)
id: ["양상우", "김개발", "박부장"],
password: ["1234", "1234", "123456"]
}
const procces = {
login: (req, res) => {
const id = req.body.id,
password = req.body.password;
if (user.id.includes(id)) { // 데이터에 있으면
const idx = users.id.indexOf(id); // 해당 id의 인덱스를 가져와서
if (users.password[idx] === password) { // 해당 위치의 패스워드랑 같으면
return res.json({
success: true // 성공했다고 알려줌
});
}
}
return res.json({
success: false, // 성공했다고 알려줌
msg: "로그인에 실패하였습니다" // 잘 출력되는지 확인해보자
});
},
}
module.exports = {
output,
procces
};
- 이렇게 API를 만들었고, 응답을 해줬으니 프론트 엔드는 이 응답을 어떻게 받아야할까?
➬ 프론트에서
.then을 이용한 데이터 처리
**const user = { // 프론트엔드에서 입력한 정보로, 해당 사용자의 인증, 인가를 해야함 그리기 위해선 인증 받은 데이터들이 있어야한다(이 데이터랑 프론트 엔드 데이터랑 비교해야함)
id: ["양상우", "김개발", "박부장"],
password: ["1234", "1234", "123456"]
}**
"use strict"
const output = {
home: (req, res) => {
res.render("./home/index") // views는 지정했기땨문
},
login: (req, res) => {
res.render("./home/login")
}
}
const user = { // 프론트엔드에서 입력한 정보로, 해당 사용자의 인증, 인가를 해야함 그리기 위해선 인증 받은 데이터들이 있어야한다(이 데이터랑 프론트 엔드 데이터랑 비교해야함)
id: ["양상우", "김개발", "박부장"],
password: ["1234", "1234", "123456"]
}
const procces = {
login: (req, res) => {
const id = req.body.id,
password = req.body.password;
if (user.id.includes(id)) { // 데이터에 있으면
const idx = users.id.indexOf(id); // 해당 id의 인덱스를 가져와서
if (users.password[idx] === password) { // 해당 위치의 패스워드랑 같으면
return res.json({
success: true // 성공했다고 알려줌
});
}
}
return res.json({
success: false, // 성공했다고 알려줌
msg: "로그인에 실패하였습니다" // 잘 출력되는지 확인해보자
});
},
}
module.exports = {
output,
procces
};
.then을 이용한 데이터 처리
fetch로 불러온 데이터는 프로미스 형태로 결과값이 반환된다
"use strict";
const id = document.querySelector("#id"),
password = document.querySelector("#password"),
loginBtn = document.querySelector("button");
console.log(id)
loginBtn.addEventListener("click", login)
function login() {
const req = {
id: id.value,
password: password.value,
}
fetch("/login", {
method: "POST", // REST API에 맞춰 보냄
headers: {
"Content-Type": "application/json" // json으로 보낸다고 말해줌
},
body: JSON.stringify(req) // JSON 형태로 바꿔서 body에 실어 보내자
})
**.then((res) => res.json()) // 응답 데이터를 가져온다
.then((res) => console.log(res)) // then을 이용해서 데이터를 가져온다 비동기 처리로 진행되기 떄문에 then을 이용해 동기 처리로 만든다
// 정리 하자면 fetch에서 login으로 POST를 보내면 해당 API에서 처리를 해왔다, 근데 처리중 응답이 생겼고, 해당 응답을 받아서 사용할려면 백엔드 API의 데이터 처리가 끝나고 나서야 사용할수 있으니, then 을 이용해 데이터가 다 처리된 이후에 res 를 이용한다
//추가적으로 파라미터로 넘기는 함수에 그 파라미터를 인자로 사용하는 함수 형태이면 축약이 가능하다 .then(console.log)
}**
- 지금 fetch를 통해 요청(body를 통해서 테이터도 보냄)을 보내고, 해당하는 응답을 프로미스 형태로 받아올것이다
- API의 데이터를 가져온뒤에 응답을 데이터를 사용해야 하기 때문에 .then을 사용
- 응답을 데이터를 가져오고 난뒤에 ⇒ 사용해보자
콘솔 말고 어떻게 처리해야할지 정해보자
"use strict";
const id = document.querySelector("#id"),
password = document.querySelector("#password"),
loginBtn = document.querySelector("button");
console.log(id)
loginBtn.addEventListener("click", login)
function login() {
const req = {
id: id.value,
password: password.value,
}
fetch("/login", {
method: "POST",
headers: {
"Content-Type": "application/json" //
},
body: JSON.stringify(req)
})
.then((res) => res.json())
.then((res) => {
if (res.success) { // 응답에서 맞다고 해주면
location.href = "/"; // 성공하면 페이지 이동
} else {
alert(res.msg) // 실패하면 메세지
}
})
.catch((err) => { // 에러 처리
console.error(new Error("로그인중 에러 발생"))
})
}
- 성공하면 홈으로 이동하게 루트 설정해주고
- 실패하면 실패한 메세지
- 에러가 생기면 .catch를 이용해 에러 코드를 발생해주자
🔙 다시, 백엔드
MVC의 모델(M) 만들기
모델?
- 데이터를 가지는 코드
- 컨트롤 하는 코드
- 데이터 로직을 처리하는 코드
"use strict";
const id = document.querySelector("#id"),
password = document.querySelector("#password"),
loginBtn = document.querySelector("button");
console.log(id)
loginBtn.addEventListener("click", login)
function login() {
const req = {
id: id.value,
password: password.value,
}
fetch("/login", {
method: "POST",
headers: {
"Content-Type": "application/json" //
},
body: JSON.stringify(req)
})
.then((res) => res.json())
.then((res) => {
if (res.success) { // 응답에서 맞다고 해주면
location.href = "/"; // 성공하면 페이지 이동
} else {
alert(res.msg) // 실패하면 메세지
}
})
.catch((err) => { // 에러 처리
console.error(new Error("로그인중 에러 발생"))
})
}
MVC의 모델(M) 만들기
모델?
- 데이터를 가지는 코드
- 컨트롤 하는 코드
- 데이터 로직을 처리하는 코드
- 데이터를 가지는 코드
- 컨트롤 하는 코드
- 데이터 로직을 처리하는 코드
등등
여튼 저번 ctrl 파일에 있는 데이터 코드를 분리하자
UserStorage.js
"use strict";
class UserStorage {
static #users = { // class 안에 변수를 선언할때는 const 이런거 안해도 된다 // 은닉화 private 함, 그렇다면 , 접근 말고 사용해야할때는??
id: ["양상우", "김개발", "박부장"],
password: ["1234", "1234", "123456"],
name: ['양땅우', '땡땡이', '곱창먹고싶다'] // 이 데이터는 말고, 위에만 받아오게 하고 싶다, 메서드를 변경하자
}
- 이제 API 쪽에서 모듈로 받아와 사용할수 있다
"use strict"
const UserStorage = require("../../models/UserStorage") // 가져오기
... 생략
const userStorage = new UserStorage(); // 스토리지 사용하기, 사실 인스턴스화 할필요는 없다,
console.log(UseStorage) // 데이터만 쓸거면 바로 접근해도 상관없다
- 하지만 바로 접근할려면 class가 변수를 사용할수있도록
static
으로 선언해줘야한다 - 하지만, 외부 에서 다이렉트로 접근하면 안되기 때문에 은닉화 해준다(#)
⇒ 그렇다면 조회는 해도, 사용은 어떻게해? undefined
가 될텐데..?
⇒ 은닉화한 메서드로 은닉화한 변수를 불러오자
"use strict";
class UserStorage {
static #users = {
id: ["양상우", "김개발", "박부장"],
password: ["1234", "1234", "123456"],
name: ['양땅우', '땡땡이', '곱창먹고싶다'] // 이 데이터는 말고, 위에만 받아오게 하고 싶다, 메서드를 변경하자
}
static getUsers(...fields) { // 메서드를 이용해서 데이터를 사용가능하게 하자 // 이 메서드를 호출할때 user의 어디 부분까지 갈껀지, 즉 매개 변수를 정호가하게 잡을수 없으니, 호출할때 인자로 넘긴 변수들을 리스트로 받아와서
const users = this.#users;
const newUsers = fields.reduce((newUsers, field) => { // 초기에 객체로 하거 newUser은 빈 오브젝트 -> id -> passwrod .. 이런식을 들어감 시작하면 필드로 들어 온 값이 할당 된다
if (users.hasOwnProperty(field)) { // user에 해당하는 키값이 있으면 (예시로 id)
newUsers[field] = users[field]
}
return newUsers // 다음 파라미터인 newUsers로 들어가게됨
}, {});
return newUsers // 마무리된 newUser
}
}
module.exports = UserStorage;
고민해 봐야할거
- 데이터 객체의 프로퍼티가 여러개 일텐데.. 메서드 매개변수 처리는 어떻게 해야하지?
- 원하는 매개변수만 가져오고 싶은데
⇒ reduce+스프레드 문법으로 해결
home.ctrl
"use strict"
const UserStorage = require("../../models/UserStorage") // 가져오기
const output = {
home: (req, res) => {
res.render("./home/index") // views는 지정했기땨문
},
login: (req, res) => {
res.render("./home/login")
}
}
const procces = {
login: (req, res) => {
const id = req.body.id,
password = req.body.password;
//const userStorage = new UserStorage(); // 스토리지 사용하기, 사실 인스턴스화 할필요는 없다, 데이터만 쓸거면, 대신 해당 변수가 정적 변수여야 클래스에서 변수에 접근 가능하다
const users = UserStorage.getUsers("id", "password")//하지만, 외부 에서 다이렉트로 접근하면 안되기 때문에 은닉화 해준다, 메서드로 불러온다
const response = {}; // 깔끔하게 정리
if (users.id.includes(id)) {
const idx = users.id.indexOf(id);
if (users.password[idx] === password) {
response.success = true;
return res.json(response);
}
}
response.success = false;
response.msg = "로그인에 실패하였습니다"
return res.json(response)
},
}
module.exports = {
output,
procces
};
🔚 돌아보기
구성
- app라는 폴더에 소스코드를 몰아넣었고
- app.js를 통해 node서버의 기본 설정을 하고
- bin폴더에 실행파일
- src에 mvc 패턴으로 분리 했다
Author And Source
이 문제에 관하여([Node.js 찍먹하기] Chapter 05 : 백엔드, 로그인 인증 기능 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://velog.io/@dndb3599/Node.js-찍먹하기-Chapter-05-백엔드-로그인-인증-기능-만들기
저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
- app라는 폴더에 소스코드를 몰아넣었고
- app.js를 통해 node서버의 기본 설정을 하고
- bin폴더에 실행파일
- src에 mvc 패턴으로 분리 했다
Author And Source
이 문제에 관하여([Node.js 찍먹하기] Chapter 05 : 백엔드, 로그인 인증 기능 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@dndb3599/Node.js-찍먹하기-Chapter-05-백엔드-로그인-인증-기능-만들기저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)