Wecode 부트캠프 -Foundation 2/인증, 인가 - 실습 (회원가입, 로그인)

Foundation Test : 최종 '회원가입' '로그인' 코드 정리 (그림 그리고 공부하며 다시보기)

JBS 12 2023. 9. 7. 20:54

추후 공부 후, 자세히 적어서 참고할 링크 

 

백엔드 서버, 데이터베이스 서버, express, mysql, Typeorm 관계

코딩하면서 항상 관계가 연결이 안 되던 게, 코드부터 치고 나서 강의를 다시 들으니 이제 연결이 된다 벡엔드는 서버를 2개 사용함 - 백엔드 서버 - 데이터베이스 서버 (mysql 설치 할 떄, mysql serve

pm-developer-justdoit.tistory.com

 

처음부터 하는 과정 담긴 것 

 

인증-인가 기능이 담긴 백엔드 API를 만드는 과제 (주황색) (깃허브 보고 수정) **

여태까지 배운 걸 모두 한번에 해보는 것이다. 빈 페이지에서부터. 처음부터 해보기 이번에는 내가 뭘 해야할지 순차적으로 적고 (말로는 잘함) 그것을 이제 컴퓨터 언어로 동사별로 쪼개서 단

pm-developer-justdoit.tistory.com

 

(1) 회원가입, 로그인, 토큰발행 [흐름]

https://pm-developer-justdoit.tistory.com/37 [Westagram Backend Project] 3. mysql Database로 유저 회원가입 하기 (주황색) -Westagram Backend Project - 여기에서 body가 없는거고, 배열 안에 있는 건 더미 데이터 [Node.js] Express

pm-developer-justdoit.tistory.com

 

[회원가입] - 아이디 패스워드 중복 확인 ** (노트 내용 추가)

최종 '회원가입' '로그인' 코드 ** (코드 완성하면 다시 복붙, 수정) - 회원가입 - 에러 핸들링 - 회원가입 - 중복확인 - 로그인 - 토큰 발행 이런 식으로 진행되었다. 처음에 회원가입은 유저 데이터

pm-developer-justdoit.tistory.com

- 회원가입 

- 에러 핸들링 

- 회원가입 - 중복확인

- 로그인

- 토큰 발행 

 

이런 식으로 진행되었다. 

 

처음에 회원가입은

유저 데이터 받아오기

유저 데이터를 데이터베이스에 저장하는 과정이였고

 

두번째 회원가입은

try if throw catch문으로 

만약 모든 경우의 예외처리에 해당되지 않을 경우에 

회원가입 시키는 것이였다. 

에러 나면, 메세지를 보여주고 회원가입 못하게 하는 것이였고. 

 

 

 

회원가입 (에러 확인, postman 실행, try- catch 구조)

이번엔 중복했는지 확인하면서 회원가입 보는 것. 코드를 만들면서 이 코드가 맞는지 확인을 하면서 가야한다. 하나할 때마다 실행시켜서 확인을 해 봐야한다. 코드를 다 짜고 나서 한번에 오류

pm-developer-justdoit.tistory.com

 


아래 코드는, 

전체 코드이다. 

 

// westagram
require("dotenv").config();
//const dotenv = require("dotenv") dotenv.config() 같은 거

// http 모듈, express 모듈 가져다 쓰는 것, require로
const http = require("http");
const express = require("express");
const cors = require("cors");
const jwt = require("jsonwebtoken"); // 불러오는

//mysql로 database 가져오는 거
const { DataSource } = require("typeorm");

const myDataSource = new DataSource({
type: process.env.TYPEORM_CONNECTION,
host: process.env.TYPEORM_HOST,
port: process.env.TYPEORM_PORT,
username: process.env.TYPEORM_USERNAME,
password: process.env.TYPEORM_PASSWORD,
database: process.env.TYPEORM_DATABASE,
});

const app = express();

app.use(cors());
app.use(express.json()); // for parsing application/json

//서버 띄우는 get
app.get("/", async (req, res) => {
try {
return res.status(200).json({ message: "Welcome to Soheon's server!" });
} catch (err) {
console.log(err);
}
});

//API 로 users 화면에 보여주기
// 프론트가 user한테 가져오는 거
//get 안의 첫번째 인자가 url --> 맨 밑의 server.listen 첫 인자 8000 -> localhost:8000/users
app.get("/users", async (req, res) => {
try {
const userData = await myDataSource.query(
// app.get은 무엇을 받는다기보다, 프론트에게 보여주는 것. 회원가입 뿐만 아니라, 추후에 저장된 정보를 DB에서
//select 은 Mysql 문이니까. query를 써서, 데이터를 가져온다. 이 데이터를 userData라는 변수에 담는다.
"SELECT id, name, email FROM USERS "
);

console.log("USER DATA:", userData);
// console.log로 출력하는게 FRONT 전달, 서버 화면에 띄우는 거 (javascript는 화면에 띄우려면 console.log로 띄어야 하니)

return res.status(200).json({
// 함수 있으니 반환
users: userData,
});
} catch (error) {
console.log(error);
return res.status(500).json({
message: error.message,
});
}
});
 
 
 [회원가입] / post만 하고 (프론트가 백엔드에게 Post 하는 것)

app.post("/users", async (req, res) => {
// postman에 http://localhost:8000/users 치는거) 8000는 아래 server 번호 참고 -> postman에 send 후에 터미널에서 확인 (프론트가 예상할 수 있게, usersignup으로 하기도-)
try {
// 1. user 정보를 frontend로부터 받는다. (프론트가 사용자 정보를 백엔드 서버에 보낸다, 요청을 보낸다)
const me = req.body;
console.log(me);

// 2. 백엔드 서버--> DATABASE 서버에 정보 저장.
// const name = me.name // 다나
// const password = me.password // 비밀번호
// const email = me.email // email
const { password, email } = me; //구조분해할당 (위랑 같은 거)
// const password = req.body.password

[Error Handling]
1] email, password가 다 입력되지 않은 경우
if (email === undefined || password === undefined) {.       // ||는 or , 반대는 &&
const error = new Error("KEY_ERROR");
error.statusCode = 400;
throw error;
}

2] 이메일이 중복되어 이미 가입한 경우
1)  유저가 입력한 Email이 우리 DB에 있는지 확인한다.
// mysql에서 use westasgram, show tables, select id, email From users where email='shlee@wecode.co.kr';
const existingUser = await myDataSource.query(`
SELECT id, email FROM users WHERE email='${email}';
`);

console.log("existing user:", existingUser); // existinguser:로 찍어봐라, 쿼리문으로 가져온 이메일로 한번 보자

2) 있으면, 즉, 이메일 중복이면 아래 if문 실행
if (existingUser.length > 0) {
const error = new Error("DUPLICATED_EMAIL_ADDRESS");
error.statusCode = 400;
throw error;
}
 
3](회원가입 시 패스워드 겹칠 수 있으니) 패스워드 중복 검사 안함
/* if ( ) {
const error = new Error("DUPLICATED_PASSWORD")
error.statusCode=400
throw error
} //if문은 if여러개 있어면 하나씩 확인하고 걸리면 throw 만나니까 catch 로 가고, 한개도 if에 해당 안 되면 바로 return status 200으로 가고 catch는 패스
*/

4]  비밀번호가 너무 짧을 때
if (password.length < 8) {
const error = new Error("INVALID_PASSWORD");
error.statusCode = 400;
throw error;
}
/*5]비밀번호에 특수문자 없을 때
// 정규식 사용 const regExp = /^[a-z0-9_]{4,20}$/; 
if (regExp) {
const error = new Error("");
error.statusCode = 400;
throw error;
}*/

3.  회원정보를 DB에 저장- mysql instert로(백엔드에는 저장되어 있음)
const userData = await myDataSource.query(`
INSERT INTO users (
name,
password,
email
)
VALUES (
'yj',
'${password}',
'${email}'
)
`);
 
4. DB 저장 여부 확인. -> mysql 가서 찍어보고 (select * from users;) 
console.log("after insert into", userData);


5.  프론트에게 알려주기, 메세지로 / 회원가입 성공, 에러 
return res.status(201).json({       //위의 try 함수에 대한 return // 되면 postman에 메세지 나옴
message: "userCreated", // 여기까지 내려왔다는 건, 오류가 없다는 것, 그러니까 회원가입,유저 생성 된 거// 위에 try안에 오류가 생길 수도 있다고 한 게 없다는 거
});
} catch (error) {
//try안에 예상되는 오류 사항 적고, if 옆의 중괄호 로 가고, 중괄호 안에 const, throw 있고, throwㄹ error로 던졌으니 , return 무시하고 다로 error로 간다
console.log(error);
return res.status(error.statusCode).json({
//만약 에러가 나면 에러 났다고 'error.message' 프론트에게 보내고, 위에는 구체적 오류 메세지// 크게 보면 구조가 try, 여기 return!
message: error.message,
});
}
});

// 오류 난 시점은 위에는 오류 없다는거 한줄씩 내려오는거니까. 서버는 항상 돌아가야 postman에서 작동 가능한데, 코드 수정 후에는 저장 후에,ctrl+c로 서버 중단 후에 다시 node 로 실행 후에 postman 실행- terminal 와서 결과 확인
 
 
// [로그인]
app.post("/login", async (req, res) => {
// postman에 http://localhost:8000/login 치는거) 8000는 아래 server 번호 참고 -> postman에 send 후에 터미널에서 확인
try {
const email = req.body.email;
const password = req.body.password;
// { email, password } = req.body

// email, password KEY_ERROR 확인
if (email === undefined || password === undefined) {
// ||는 or , 반대는 &&
const error = new Error("KEY_ERROR");
error.statusCode = 400;
throw error;
}

// 1. Email 가진 사람 있는지 확인
// if 없으면 -> Error
// 있으면 -> 정상 진행 (if 문 필요 없음)
const existingUser = await myDataSource.query(`
SELECT id, email, password FROM users WHERE email='${email}';
`); //sql문은 백엔드까지만 보내고, DB에는 안 보냄 (프- 백- DB)
// sql에서 email만 가져와도 되는데, 2번에서 해당 email에 해당되는 password를 가져와야하니까, 여기에서 한꺼번에 써주는것/ id, email, password를 가져와라. 변수 email이 문자열'적은 email'에 해당되는 것으로

console.log("existing user:", existingUser);

// email 없으면 에러 = 중복 없을 떄
if (existingUser.length === 0) {
// existing user 이용해서 판별`
const error = new Error("DUPLICATED_EMAIL_ADDRESS");
error.statusCode = 400;
throw error;
}

// 2. Password 비교 (로그인떈 해야함. 같아야 하니까 무조건)
// 유저가 입력한 password === DB에서 가져온 PASSword
// if 다르면 -> Error
// 같으면 -> 정상 진행. if 필요없음

//2-1.아무나의 패스워드가 아니라, 위에 친 이메일 소유자에 해당되는 패스워드여야 함
//2-2.데이터베이스에 있는 패스워드가, 지금 친 패스워드랑 같은지 확인 / 그러려먼, 지금 친 패스워드와 이메일 출력

console.log("existing user:", existingUser); //"existingUser:"는 문자열로 나오고, existingUser는 변수로 나오고/
console.log("email", "password"); //값을 찍어내는 게 아님, 들어오고 있는지 확인하려고/ 우리가 확인 한거 // 'password'는 텍스트, 아래에 있는 password는 변수
// //existingUser 는 객체로 key:value로 나오고, 그 안에 배열이 들어감, existingUser[0]={id: 5, email: 'y123@email.com', password: '123456789@2' } existingUser.id = 5 (dot notation) //

// 2-2 -> 지금 친 password 출력 // 지금 친 거는 request body에 들어있음
console.log(password); //console.log(req.body.password); -> const password = req.body.password 인데, const로 이미 passoword 안에 들어있으니까, password만 쳐도 됨/ 이제 찍자. 찍는 건 console.log로

//2-1 -> 위에서 select한 유저의 password 출력 (왜 select? 데이터베이스- mysql)
//위에서 select 유저의 이메일 가져오기
/*
const existingUser = await myDataSource.query(`
SELECT id, email FROM users WHERE email='${email}';
`) // password 기준으로 사람 찾아오면 안됨. email로 찾아야 함. // existingUSer 변수 중복으로 1번에 같이 넣어둠/ 근데 1번에서 이메일만 가져오는거니, 1번에서 패스워드, id도 가져오게 아예 코드 넣기
*/
// (sql문은 백엔드까지만 보내고, DB에는 안 보냄, 프>백>DB)\

// 2-2 -> 지금 친 패스워드와 데이터베이스에 있는 패스워드가 같은가
if (password !== existingUser[0].password) {
// if (req.body.password === userData.password) {
//지금 친 패스워드 = 변수 password --> 이거 맞는지 확인
const error = new Error("INVALID_PASSWORD");
error.statusCode = 400;
throw error;
}
// if 절을 'const inValidPassowrd = password !== existingUser[0].password; throwError(wrongPassword, 400, "AUTHENTICATION_FAILED");

//토큰 generate token / return 전에 token 만들기

// 1. use library allowing generating token
// 2. {"id": 10}
const token = jwt.sign({ id: existingUser[0].id }, "rekey"); /// mysql을 데이터베이스라고 부르고, 회원가입을 했으면, 데이터베이스에 회원정보가 잘 들어갔는지 mysql 가서 확인 (mysql을 데이터베이스로 부른다)

// 3. signature /// mysql 가서 접속, 데이터베이스 불러오기 (show databases;)/ 여기 안에 westagram 데이터베이스 사용할거야 use westagram; / westagram 안에 회원가입이니까 users 테이블을 다 보여줘 select * from users;/그러면 여기 아래에 추가된 사용자 이름, 비번, 아이디 뜨면 성공
return res.status(200).json({
message: "LOGIN_SUCCESS",
accessToken: token, //respond 보낼 때, 로그인 메세지와 함께 token 발행 (준다)
});
} catch (error) {
console.log(error);
}
}); //existingUser 는 객체로 key:value로 나오고, 그 안에 배열이 들어감, existingUser[0]={id: 5, email: 'y123@email.com', password: '123456789@2' } existingUser.id = 5 (dot notation) //

// 과제 3 DELETE
// 가장 마지막 user를 삭제하는 엔드포인트
app.delete("/users", async (req, res) => {
try {
//query문
} catch (err) {
console.log(err);
}
});

// 과제 4 UPDATE
// 1번 user의 이름을 'Code Kim'으로 바꾸어 보세요.

app.put("/users/1", async (req, res) => {
try {
const newName = req.body.data.name;
} catch (err) {
console.log(err);
}
});

// express app 으로 서버를 만듭니다.
const server = http.createServer(app);
// 서버를 시작하는 함수
const start = async () => {
try {
server.listen(8000, () => console.log(`Server is listening on 8000`));
} catch (err) {
console.error(err);
}
};

myDataSource.initialize().then(() => {
console.log("Data Source has been initialized!");
});

start();

// 프론트에게 받아오려면 '/user' 바꾸고, localhost는 나 자신이니까, 내 ip 주소를 넣어서 들어가면 url 됨 / 프론트에겐, 내가 ip 주소와 port 번호 주면, 프론트에게 회원가입 창 뜸
// ip 주소는 터미널에 'ipconfig getifaddr en0' 치면 나옴 =10.58.52.90
// 저장은 comman+s , 서버 끄는 건 ctrl+c (안 쳐진다면 termninal에 넣어야), 항상 서버 키기 (node app3.js)

 

중복 if () 에 들어가는 것은 

내가 해본 것인데 

맞는지 확인 후 다시 업데이트 해야 한다. 


회원가입 코드 다시 간단하게 해보면

app.post("/users", async (req, res) => {
try {
const me = req.body;
console.log(me);
const { password, email, nickname } = me;
 
// 예외처리 email, password가 다 입력되지 않은 경우
if (email === undefined || password === undefined) {
const error = new Error("KEY_ERROR");
error.statusCode = 400;
throw error;
}
 
// 예외처리 이메일이 중복되어 이미 가입한 경우
const existingUser = await myDataSource.query(`
SELECT id, email FROM users WHERE email='${email}';
`);

console.log("existing user:", existingUser);
 
if (existingUser.length > 0) {
const error = new Error("DUPLICATED_EMAIL_ADDRESS");
error.statusCode = 400;
throw error;
}
 
// 이메일에 . 과 @ 필수포함
// 정규식
const emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
 
if ( ! emailRegex.test(email) ) {
const error = new Error("INVALID_EMAIL_FORMAT");
error.statusCode = 400;
throw error;
}
 
// 비밀번호가 10자리 미만일 때
if (password.length < 10) {
const error = new Error("PASSWORD_Too_Short");
error.statusCode = 400;
throw error;
}
 
//instert로 회원정보를 DB에 저장해라 (백엔드에는 저장되어 있음)
const userData = await myDataSource.query(`
INSERT INTO users (nickname,password,email)
VALUES ('${nickname}', '${password}', '${email}')
`);
 
//DB 저장 여부 확인
console.log("after insert into", userData);

// 회원가입 성공 // 성공 메세지를 프론트에게 보내라
return res.status(201).json({
message: "userCreated", 
});
} catch (error) {
console.log(error);
return res.status(error.statusCode).json({
message: error.message,
});
}
});
 

 

 

로그인 부분 다시, 간단하게 설명하면,

app.post("/login", async (req, res) => {
try {
const email = req.body.email;
const password = req.body.password;
 
// 1. key error 
if (email === undefined || password === undefined) {
const error = new Error("KEY_ERROR");
error.statusCode = 400;
throw error;
}
 
// 2. email 확인 (데이터베이스 email 에 지금 친 email 과 같은 게 있는지) 
const existingUser = await myDataSource.query(`
SELECT id, email, password FROM users WHERE email='${email}';
`);
 
//console.log("existing user:", existingUser);
 
// existingUser 객체에 아무것도 없으면, 같은 이메일이 없다는 것이니 에러 메세지 (if, 중복 없을 떄)
if (existingUser.length === 0) {
const error = new Error("DUPLICATED_EMAIL_ADDRESS");
error.statusCode = 400;
throw error;
}
 
// 3. 패스워드 확인
console.log(password);
// 지금 친 패스워드와, 데이터베이스에서 가져온 existingUser객체에서 찍은 password 가 같지 않으면, 에러 
if (password !== existingUser[0].password) {
 

근데 저게 왜 0번째인지 모르겠지만

const error = new Error("INVALID_PASSWORD");
error.statusCode = 400;
throw error;
}
 
 
// token 만들기 (데이터베이스 id 담아서)
const token = jwt.sign({ id: existingUser[0].id }, "rekey");
return res.status(200).json({
message: "LOGIN_SUCCESS",
accessToken: token,});
} catch (error) {console.log(error);}
});

이제 부분별로 뜯어보며 분석해보자

 

 

위에서부터 뜯어볼 것이다, 

 

 

 

1. 설정 코드 

http 모듈 쓸 거고 

express 모듈 쓸 거고 

typeorm 으로 가져오고 

express를 json을 쓰겠다. 

const {DataSource} = require("typeorm"); 

typeorm으로 부터 datasource를 가지고 와라 

- DataSource는 typeorm 만든 typeorm 개발자들이, 데이베이스 연결 쉽게 하라고 미리 만들어놓은 객체 

- 우리는 이걸 사용

위에는 한줄 한줄 변경해서, 여기서 변한 부분 비교해보기

type: 'mysql'

host: '내 서버니까 localhost'

port: mysql 데이터베이스도 서버이기에,

우리가 서버 열 때 사용했던 8000 같이, 

데이터베이스 서버 포트는 보통 '3306' 씀 

username: 'root'

password: 'mysql password'

databaes: '연결할 database name'

typeorm이 실제로 mysql에 로그인해서 가져오는거기 때문에. 

 

그러기에, database , username, password 잘못 쓰면 

없다고 터미널에 뜸

 


2. app.get


뜯어서 보자

2-1) 첫번째 app.get  

백엔드가 프론트에게 회원 정보를 가져온다는게 아님.

여기는 프론트엔드가 나중에 백엔드에게 정보를  get한다는것

// 여기에서는 서버 작동이지, 무언가를 받아오는게 아님.

postman에서 확인해본다. 주소를 쳐본다
사이트에도 주소를 쳐봐서 확인해보면&nbsp; 서버 작동한다! ㅎㅎ

 


2-2) 두 번째 app.get  

/users 사이트에서

req로 받아온 req.body에 담긴

회원가입하려고 고객이 적은 email, password 정보를  --> select id name email FROM USERS 테이블 --> mysql 테이블 

프론트엔드가 백엔드에게 받아온다.

 

(비단 회원가입할떄 뿐만 아니라, 나중을 위해

로그인 등 할 떄 필요하겠지?) 

 

 

 

 

프론트가 백엔드 서버에서 정보를 받아서 화면에 보여주는 부분도,

쿼리문으로 코드 칠 것 

(mysql 데이터베이스에서 정보를 가져와서) 

 

const userData= await myDataSource.query("SELECT id, name, email From USERS"); 

이부분은 우리가 실행 하는게 아니라, 프론트가 우리에게 요청할 때에만

 

코드에서 찍어내보는 방법
console. log 쓰는데, 

이 부분에서
const userData= await myDataSource.query("SELECT id, name, email From USERS"); 가 잘 갔나 확인 할 거면, 
1) console.log ( "User Data: " , userDate) 를 vscode javascript에 치고, 
- 확인하기 쉽게 string으로  User Data:  한 것
2) postman - get - http://localhost:8000/users
- app.get("/users", ) 이니까
3) postman send 돌리고, terminal 에서 확인하면, 

이런 형태로 나옴

결과 나왔으니, mysql 데이터베이스에서, 백엔드 서버로는 잘 넘어왔다.

 

 

 

app.post에서 

1) 프론트가 백엔드에게 정보 준다 (백엔드는 프론트에게 정보 받는다) -- 백엔드 서버 

const me = req.body;
console.log( "Me: ", me);

--> 정보가 잘 가는지 확인하는 과정 

postman - post - http://localhost:8000/users (아직 완성 안했지만 에러 나는건 당연하고, 일단 잘 찍히는지 console.log로 확인)

 

2) 백엔드 서버에 있는 정보를 데이터베이스에 저장해야 함!  -- 데이터베이스 서버 

 const name = me.name
 const password = me.password
 const email = me.email 

ME 안의 name을 불러와서, const name이라는 변수를 생성해서 ME라는 객체에 접근해서 name을 가져온 것

 

근데 팁! 

 const password = me.password
 const email = me.email  

= const { password, email } = me; 

 

다시 돌아와서, 

const userData = await myDataSource.query(`
INSERT INTO users (name, password, email) VALUES ( 'yj', '${password}', '${email}')`
);

데이터베이스에 추가해라 -> select 아닌 insert into! 

( '$password' '$email'은 문자열로!)

 

이제 잘 됐는지 확인 위에 프론트인척, Postman - post로 해보기 

 

 

3) 데이터베이스에 잘 저장됐는지 저장 여부 확인

terminal > mysql 로그인 > mysql select * from users

다시 다 찍어내서 users 테이블에 추가됐는지 확인 

(꼭 users 테이블이 아니라, 내가 만든 테이블 이름) 

console.log('after insert into', userData)

이거 해서, Postman -post 찍어내면, terminal에 나오는데,

affectedRows를 보면 1줄 추가 된 거 알 수 있음

데이터베이스 서버가 백엔드 서버에게 알려주는 것

 

plus, 객체이기에 affectedRows만 찍어내면 

console.log('after insert into', userData.affectedRows)

1 이라고 나옴. 

 

plus, 데이터베이스 ID 몇번에 추가됐는지 알고 싶으면 이렇게 찍어내면

console.log('after insert into', userData.insertedId)

7 이런 식으로 나옴

 

4) 프론트에게 response (잘 저장 됐다) 

백엔드가 메세지에게 메세지 보내줌 -> 프론트는 메세지 보고 알 수 있음  'userCreated' 

return res.status(201).json({
message: "userCreated",});
} catch (error) { console.log(error);
return res.status(error.statusCode).json({message: error.message,});
}
});

 

-- 중간중간 확인을 얼마나 자주 하느냐에 따라, console.log 들어가는 거 


3. app.post

3-1. app.post

/users 회원가입을 할 때에 

프론트엔드가 백엔드에게 회원정보를 req.body에 담아서,  me로 변수화해서 post 한다. 보낸다. 

 

 

myDatatSource를 query문으로 instert into로 회원가입한 정보를 추가한다. 

근데 이거를 userData라는 변수에 담아서 준다. 

 

잘 오면, 메세지를 보낸다. userCreated! 

 

안 오면, errorCode를 를 보낸다

 

 

 

 

3-2. app.post

프론트엔드가 백엔드에게 login 을 치고 들어와서 post한다. 

 

req.body에 담아서. 근데 req.body에 담았던 email, password을 변수에 담아와서

(구조만 보자 안에 if 있음)  


다른 버전으로 나를 위해 썼던 주석 빼고 , console.log 빼고 보기 

const dotenv = require("dotenv");

dotenv.config();

const http = require("http");
const express = require("express");
const cors = require("cors");
const jwt = require("jsonwebtoken");

const { DataSource } = require("typeorm");

const myDataSource = new DataSource({
type: process.env.TYPEORM_CONNECTION,
host: process.env.TYPEORM_HOST,
port: process.env.TYPEORM_PORT,
username: process.env.TYPEORM_USERNAME,
password: process.env.TYPEORM_PASSWORD,
database: process.env.TYPEORM_DATABASE,
});

const app = express();

app.use(cors());
app.use(express.json());

app.get("/", async (req, res) => {
try {
return res.status(200).json({ message: "Welcome to Y's server!" });
} catch (err) {
console.log(err);
}
});

app.get("/users", async (req, res) => {
try {
const userData = await myDataSource.query(
"SELECT id, name, email FROM USERS "
);
console.log("USER DATA:", userData);

return res.status(200).json({
users: userData,
});
} catch (error) {
console.log(error);
return res.status(500).json({
message: error.message,
});
}
});

app.post("/users", async (req, res) => {
try {
const me = req.body;
console.log(me);

const password = me.password;
const email = me.email;
// const { password, email } = me;

//1
if (email === undefined || password === undefined) {
const error = new Error("KEY_ERROR");
error.statusCode = 400;
throw error;
}

//2
const existingUser = await myDataSource.query(`
SELECT id, email FROM users WHERE email='${email}';
`);

console.log("existing user:", existingUser);
if (existingUser.length > 0) {
const error = new Error("DUPLICATED_EMAIL_ADDRESS");
error.statusCode = 400;
throw error;
}

//3
if (password.length < 8) {
const error = new Error("INVALID_PASSWORD");
error.statusCode = 400;
throw error;
}

const userData = await myDataSource.query(`
INSERT INTO users (
name,
password,
email
)
VALUES (
'yj',
'${password}',
'${email}'
)
`);

return res.status(201).json({
message: "userCreated",
});
} catch (error) {
console.log(error);
return res.status(error.statusCode).json({
message: error.message,
});
}
});

app.post("/login", async (req, res) => {
try {
const email = req.body.email;
const password = req.body.password;

if (email === undefined || password === undefined) {
const error = new Error("KEY_ERROR");
error.statusCode = 400;
throw error;
}

const existingUser = await myDataSource.query(`
SELECT id, email, password FROM users WHERE email='${email}';
`);
console.log("existing user:", existingUser);

if (existingUser.length === 0) {
const error = new Error("DUPLICATED_EMAIL_ADDRESS");
error.statusCode = 400;
throw error;
}

// console.log("existing user:", existingUser);
// console.log("email", "password");
// console.log(password); = console.log(req.body.password);

if (password !== existingUser[0].password) {
const error = new Error("INVALID_PASSWORD");
error.statusCode = 400;
throw error;
}

const token = jwt.sign({ id: existingUser[0].id }, "rekey");

return res.status(200).json({
message: "LOGIN_SUCCESS",
accessToken: token,
});
} catch (error) {
console.log(error);
}
});

const server = http.createServer(app);
const start = async () => {
try {
server.listen(7801, () => console.log(`Server is listening on 7801`));
} catch (err) {
console.error(err);
}
};

myDataSource.initialize().then(() => {
console.log("Data Source has been initialized!");
});

start();

특수문자가 들어갈 때 참고할 것

 

https://whitepro.tistory.com/245 

 

정규표현식, 비밀번호 특수문자 포함(자바, 자바스크립트, 파이썬)

비밀번호 : 문자+숫자+특수문자 가능한 정규식(22.03.02 추가) 영어 및 숫자를 허용하며, 숫자키와 관련된 특수문자만 허용한다. 일반적인 방식이다. ^[a-zA-Z\\d`~!@#$%^&*()-_=+]{8,24}$ ^[ ] : 대괄호 안의

whitepro.tistory.com

 


추가로 알아야 할 문법

 

console.log는 함수의 값을 가져오는 게 아니라, return이 그 역할인데, 

그게 우리 눈에 안 보이니 console.log로 우리를 위해 찍어보는 것

 

첫 인자는 " " 문자열인데 

우리가 우리 위해  찍는 거니 보기 편하라고 

: 를 쓴 거다. 

그 뒤엔 변수로 가져올테니.