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

Foundation Test: 인증-인가 기능이 담긴 백엔드 API를 만드는 과제 (주황색) **

JBS 12 2023. 9. 10. 11:50

여태까지 배운 걸 모두 한번에 해보는 것이다.

빈 페이지에서부터. 

 

처음부터 해보기 

이번에는 내가 뭘 해야할지 순차적으로 적고 (말로는 잘함)

그것을 이제 컴퓨터 언어로 동사별로 쪼개서 단계 써서 하기 (데이터 받아오기 이런 표현이 아직 어색했다) 

 


  • 개인의 로컬 디렉토리에 아래 문제 내용에 맞는 미니 어플리케이션 코드를 작성합니다.
  • 최종적으로 올바르게 기능하는 어플리케이션을 개인의 Github 레포지토리에 Push 합니다. 해당 레포지토리는 저희가 접근할 수 있게 Private이 아닌 Public으로 생성하여주세요!
  • 올바르게 기능하였는지 POSTMAN, 데이터베이스내 저장 데이터 등의 통신 결과를 스크린샷 촬영을 합니다.
  • 해당 Github 레포지토리 링크와 스크린샷을 주어진 클래스룸에 제출합니다.>wecode | Backend Mini Project Test
 

>wecode | Backend Mini Project Test

아래의 체크리스트는 지난 Foundation 기간동안 여러분들이 학습해주신, 기초 프로그래밍 지식입니다. 아래의 내용을 참고하여서 작은 단위의 웹 어플리케이션 프로그램을 작성하여 주세요. 작성

www.notion.so

 

문제에 접근하는 전략을 잘 세워, 스스로의 기초 웹 개발 코드 작성 능력을 점검해주세요.


 

[문제 해결 전략- 동사 위주로 해보자]

 

 

1. 개인 로컬 디렉토리 만들기 --> 이게 아니라 개인 repository 만들기  (궁금한 점, 로컬 디렉토리인데 왜 repositoryㅇ지? 나는 터미널에 cd desktop > cd vscode> cd wecode > mkdir 부터했다... )

2. 깃허브에 new repository 만들기 

깃허브 - repository - new - create 

3. 개인 repository와 깃허브 repository 연결 

3-1. 깃허브 repository url 받기 (clone)

3-2. git remote add origin 주소

3-3. git remote -v : 로컬저정소와 원격저장소 연결 완료

git push -u origin master

(여기서 의문점은 branch 부터 만드는지, github repository부터 만드는지, add-status-commit-push를 가장 마지막에 하는지 순서를 모르겠다는 점이다) 

git branch  

 

3. postman, mysql 실행시키고 결과 보기 

4. 성공시킨 코드를 깃허브 개인 디렉토리에 push (코드 업로드, 개인 폴더에)  --- 깃허브는 코드 공유하는 곳이니까

 

 


일단 이렇게 하고, 

 

문제를 보자.

인증-인가 기능이 담긴 백엔드 API를 만들기 

아예 처음부터 코드를 짜는 것이다. 

☑️ 활용해야하는 기초 지식 내용

  • 초기 환경 세팅 -
  • TypeORM을 이용한 로컬 DB 구축 및 연동 - 
  • DB 스키마 작성 및 migration 파일 구축 - 
  • 환경변수 파일 작성    - 
  • .gitignore 파일 작성   - 
  • 회원가입 signUp API 구현
    • 비밀번호 암호화 및 저장 2) -
    • 회원가입 시 필요한 예외처리 1)  -
    • 회원가입 로컬 데이터베이스에 저장된 유저의 계정 스크린샷 촬영 3) 
    • 회원가입 POSTMAN 등의 정상 통신 결과, 스크린샷 촬영 4) 
  • 로그인 signIn API 구현
    • user 이메일 확인  - 
    • 암호화된 비밀번호 비교 -
    • 로그인시 필요한 예외처리 
    • JWT 발급 - 
    • 로컬 데이터베이스에 저장된 유저의 계정 스크린샷 촬영
    • POSTMAN 등의 정상 통신 결과, 스크린샷 촬영

 


깃허브에 올릴 내 폴더부터 만들자

 

1. 터미널 키기

2. cd desktop

3. cd vscode cd wecode 

4. wecode폴더 안에 내 이름으로 된 디렉토리 만들겠다 mkdir [내 이름] 

 

 

깃허브에 가서 new repository 생성 

 


  • 초기 환경 세팅 (터미널)

  • TypeORM을 이용한 로컬 DB 구축 및 연동 (vscode에서 파일 열기, 터미널 아래 틀어서 같이 하기, package.json에서 설치된 리스트 볼 수 있음)

typeorm 설치와 express/ mysql database 연결 , 코드 분석 

 

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

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

pm-developer-justdoit.tistory.com

 

내가 이전에 했던 것 참고해서

 

[Express 초기 환경세팅] 2. database 연결- dbConnection 설정

-Westagram Backend Project - TypeORM 설치 및 적용 dbConnection 정상 작동 확인 아래 링크에서 진행했던 TypeORM 설치에서 이어져서, [Express 초기 환경세팅/ TypeORM 설치] **(주황색) -Westagram Backend Project - 1. Express

pm-developer-justdoit.tistory.com

 

위에 링크의 설치 파일 외에도 

npm install mysql2

npm install nodemon

npm install http

npm install express 도 해줘야 한다. 

 

  • 환경변수 파일 작성

  • .gitignore 파일 작성

https://pm-developer-justdoit.tistory.com/33

내가 이전에 했던 것 참고해서

 

[Express] .gitignore 생성

지금은 멘토님이 만들어주신 .gitignore 으로 들어가지 않아도 될 파일을 하는데, 프로젝트 할 때부터는 내가 직접 새로 .gitignore 생성해야하니. https://www.notion.so/wecode/Git-gitignore-24c8a014f7344c3a8899dd4e65

pm-developer-justdoit.tistory.com

 

  • 로컬 DB 구축 및 연동  을 하려는데 계쏙 오류 나는데 

에러 1. 

liver server 의 port 넘버가 이미 있다는 것이다 ...

원래 8000이였는데 7000으로 바꾸어보았다 

 

근데도 또 있다고 해서, 내가 7001로 하려다가 아싸리 7801로 하니까 됐다! 

7801 서버가 리스닝 하고 있다!!!!

 

 

서버 포트 번호 —> 내 서버에서 8000이 이미 돌아가고 있어서 .

그 서버를 꺼야 함. 전세계 사람들이 모두 id처럼 중복 안 되게 쓰는게 아니라.

 

그런데, 컴퓨터는 한번에 하나씩만 할 수 있다고 하지 않았는가?

liver server은 해결됐는데, 데이터베이스 문제가 있다고 또 보여줬다.

이거는 에러2 에서 해결할 것.

 

에러2-1. 

 

에러 2-1-1. 터미널에서 에러를 읽은 결과, mydb 라는 데이터베이스는 없다고 나왔었다. 

난 친 적 없는, 도대체 mydb가 어딨는데? ctrl+f 로 찾기 해도 없는데..

.env파일에 가보니, 거기에 디폴트로 typeorm database=mydb로 되어있었다. 

 

에러2-2-2. 그리고 계속 같은 또 에러가 나서, 

- ER_ACCESS_DENIED_ERROR Access denied for user 'root'@'localhost' (using password: YES)

그대로 복사해서 구글링해보니, 

password 문제라고. 

 

생각해보니, .env 파일에 password도 디폴트였지? 

 

typeorm은 mysql을 연결해주는 것이니, mysql 비밀번호와 mysql에서 만든 데이터베이스 이름을 넣어야 

여기 연동된다!!!! 

 

.env파일에서 password와 database 를 수정해야했다. 가져올 내 패스워드와 데이터베이스 

--> 임의로 지정된 두개의 값을 변경해야

password, mydb로 되어있는 것을 내 root password 넣고, 내가 mysql에 만든 데이터베이스 이름 넣기  (create databases [ 데이터베이스 이름])

그런데 이 부분 port 는 liver server port 번호 아닌거같은데 뭐지? 

mysql 로그인 후에 데이터베이스 보기, 내가 새로 만든 데이터베이스가 필요하니까 create database 후에 use database를 할 것이다.
mysql 로그인 후,

그렇다면, mysql에 가서 database 만든 후에, 

.env에 넣기 

 

에러 3

그리고 또 나온 에러는, 

내가 파일명을 jjj로 해놓고 jj 로 쳐서 그랬었다 

jjj로 바꾸고 나서

 

데이터베이스 서버 연결 성공!!!! 

 

이번에는 그 누구의 도움도 받지 않고 혼자 했다!!!

그전에는 코드 뭐가 뭔지도 모르고 

하기에 급급해서 뭘 한 건지 몰랐는데

처음부터 혼자 세팅해보니 코드의 흐름이 보였다. 정말 설계하는 느낌! 

 

 

[express 초기 환경 세팅 후/ typeorm 설치 후 /데이터베이스 연결까지의 코딩]

이제 여기 사이사이에 계속 채워넣을 것이다

const dotenv = require("dotenv");

dotenv.config();

const http = require("http");
const express = require("express");

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(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,
});
}
});

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();

 


  • DB 스키마 작성 및 migration 파일 구축

데이터베이스만 임의로 mysql에 만들어놓았기에, 

터미널로 가서 mysql에서 

1) 안에 테이블을 만들고, 

2) 안에 데이터도 추가해야 한다. 

 

우리는 회원가입 로그인 api를 해야하니까, user table만 만들면 됨

 

https://pm-developer-justdoit.tistory.com/31

내꺼 참고 

 

[MySQL로 Database 만들기] 1. DDL, DML 사용 (ERD 연결)

https://pm-developer-justdoit.tistory.com/371번 데이터베이스 만들기, 각 테이블 만들기 스키마 = 데이터베이스 여러 테이블들이 모인 거 = 데이터베이스 뭐가 테이블이고 데이터베이스이고, 이름 읽을 줄

pm-developer-justdoit.tistory.com

 

에러1. incrememt -> increment 

에러2. vachar -> varchar

혼자서 찾아냈다. 이제 이 정도는 에러를 혼자 찾아내는 건 터득한 거 같아서 뿌듯하다.

컴퓨터 언어가 코드가 익숙해져야 가능한 거 같다.

이렇게 하다보니 정말로, 왠만해서는 도움 받지 않고, 물어보지 않고 혼자 해서 될때의 성취감을 맛보고 싶다.

되는 것에 급급하기보다, 오래 걸리고 1-3시간 걸려서라도 되는 그 느낌을 이제 알게 되었다. (어느 정도 알아야 고민하는 시간, 구글링이 효용성있다는 것)

근데 또 에러가 나서 다시 봐야 한다. 

 

모르겠다... help! 

create database [데이터베이스 이름] 은 했고
지금 create table users( ) 하는 단계인데
1) create table users 의 'users'가 맞는지
 2) 제가 쓴 코드 형태, 내용이 맞는지 모르겠다

 

알고보니 버전마다 다른데, 어쨌든 나는 아래와 같이 CURRENT_TIMESTAMP를 DEFAULT NOW()로 수정했고, 

CREATE TABLE users( 

id INT NOT NULL AUTO_INCREMENT, 

name VARCHAR(50) NOT NULL,  

email VARCHAR(200) NOT NULL, 

password VARCHAR(200) NOT NULL, 

created_at TIMESTAMP NOT NULL DEFAULT NOW(), 

updated_at TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP, 

PRIMARY KEY (id) );

 

 

error 표시는 안 났다.

 

그런데 그래서 테이블이 만들어진건가? 만들어졌다는건가? 

 

나의 시도 

1) ;를 다시 쳐봄 

이거 아닌데,,

2)테이블이 만들어졌는지를 보자, select * from users 해봄 --> 비었다고 나옴 --> 왜 비었지? 

 

3) 그럼, create table을 한번에 말고 하나씩 만들자 해보자 (create 여러개)

아니라네

 

4) 이것도 아니면, 그럼 우리가 이미 user라는 테이블 이름을,

다른 westagram테이블에서 쓰고 있어서 그런가? (아님 테이블이 만들어진건가?)

그럼 일단 table 이름을 다른거로

새로운거로 시도해보자. 49test로 바꿔서 만들어보자

 

4-2) 한줄만은 안 된다는 거 같으네?

--.> 이번에 create 할때에는 다 넣어서 해보았다. 

 

 

어라? 위에서 내가 users로 만든 테이블이랑 똑같은 문구 

[Query OK, 0 rooots affected (0.04 sec)] 이 나오네 

 

그렇다면, 둘다 만들어졌다는 거 같은데? 

한번 테이블 찍어내보자. 

 

select 말고도 desc 가 있었는데 그거로 해볼까? 

5) 테이블이 만들어졌는지를 보려면  select users가 아니라 desc users구나

 

진짜 혼자 박수치고, 옆에 동기랑 하이파이브하고 난리였다. 

 

6) 그러면 나 테이블 두개 만든거네? 아까 만든 users도 찍어내보자! 

와우 됐어 ㅎㅎㅎ

  1. 결과 못 알아들어서  [Query OK, 0 rooots affected (0.04 sec)] 
  2. select를 해서 (desc했어야) 

 

 

[그렇다면 select와 desc 차이는?]

desc는 내가 만든 테이블의 column정보를 볼 때 사용

select는 내가 원하는 조건의 쿼리문을 다시 내가 원하는 조건의 값을 찾는 문장

 

아하 mysql이 쿼리문이니까 만들고 나서 query ok 라고 뜨는 거구나,,

 

0 row 라고 뜨는건 data를 아직 추가 안해서 그런건가? 

 

Query OK, 0 rows affected (0.01 sec)

데이터 추가 안해서 그런거지만  의미는 "쿼리문 잘 받았고, 확인해 봤는데 0개의 결과값이 나왔어 (0,01초 걸림)"

 

 


자, 이제까지한거는 테이블 만든거고, 이제 안에 값을 추가 해야 하는지 알았는데(insert) 

 

아니였다. 

 

 

일단 get , post 의미가 뭘까? 

프론트엔드 기준인데, 프론트엔드가 get 백엔드에게 정보를 받는다는 것

백엔드에게 정보를 준다; 프론트엔드가 post한다. 

 

 

1-1. app.get

 

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

  // app.get은 무엇을 받는다기보다, 프론트에게 보여주는 것. 회원가입 뿐만 아니라, 추후에 저장된 정보를 DB에서.

select 은 Mysql 문이니까.

query를 써서, 데이터를 가져온다. 이 데이터를 userData라는 변수에 담는다.

postman에서 확인해본다. 

주소를 쳐본다 

7801 과 7801/ 과 같다.

아래에 메세지 잘 뜨네! 

여기에서 port 넘버를 위에 적어서.

 

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

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

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


사이트에도 주소를 쳐봐서 확인해보면 

서버 작동한다! ㅎㅎ 

 

1-2. app.get

그렇다면, 바로 아래에 있는 app.get은 무엇인가?

/users 사이트에서 req로 받아온 req.body에 담긴 

회원가입하려고 고객이 적은 email, password 정보를, 

프론트엔드가 백엔드에게 받아온다. (로그인 등 할 떄 필요하겠지?) 

 


2-1. app.post

/users 회원가입을 할 때에

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

 

 

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

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

 

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

 

안 오면, errorCode를 를 보낸다

 

 

2-2. app.post

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

 

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

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

 

 


// table만 만들어놓고, postman에서 회원가입하려는 유저 정보 가져온다

 

왜냐하면, post로 프론트엔드가 get으로 

회원가입한 고객의 이메일, 비밀번호를 주면

 

req.body에 담겨서 오고

그것을 우리가 받고 

 

미리 만든함수에, if 에러에 안 걸리고 

회원가입 성공하면, 회원가입 성공했다고 프론트엔드에게 알리고, 메세지를 보내야 하니 

post 하는. 

(백엔드는 그래서 post만 한다고) 

 

app.post("/users", async (req, res) => {

  try {

const me = req.body;
console.log(me);

 


  • 회원가입 signUp API 구현  --- 순서 
    • 비밀번호 암호화 및 저장 2) 
    • 회원가입 시 필요한 예외처리 1) 
    • 회원가입 로컬 데이터베이스에 저장된 유저의 계정 스크린샷 촬영 3) 
    • 회원가입 POSTMAN 등의 정상 통신 결과, 스크린샷 촬영 4) 

 

 

회원가입 예외처리 

 

비밀번호 암호화 및 저장


  • JWT 발급 

이거부터 하자. 

npm install jsonwebtoken --save        // terminal에 썼다 --> 터미널과 vscdoe의 터미널을 왔다 갔다 하면 리셋되는구나 

 

 

const jwt = require('jsonwebtoken');    //vscode javascript 에 쓰고 

 

 

토큰? 백엔드가 매번 프론트에게 사용자의 로그인 기록을 주는데, 비밀번호를 암호화해서 줌 --> 로그인 기록 유지 하는 기능 (다른 거 하는 동안) 로그인 성공한 시점에 토큰을 발급.

그 토큰의 이름이 jsonwebtoken해서 jwt

 

jwt 는 토큰을 암호화 , 토큰을 주고 나면 프론트가 또 언제 쓰느냐? 

토큰은 내가 로그인 했었어 알려주는거,

 

- header 에 token type, 알고리즘

- payload: id, 등 유저 데이터 정보  (만약에 비번이 있으면, 해커가 뚫으면 다 뚤리니까) 

- signature :우리 회사 서버라는 뜻 

 

 

토큰 코드 위치는

로그인 성공 후, return 전이다. 


회원가입 로컬 데이터베이스에 저장된 유저의 계정 스크린샷 촬영 

 

이걸 하기 위해서는 일단, 

내가 프론트인 척하고,

 

postman에 가서, get 해야 한다. 

 

프론트가 user에게 받아온 정보를 

req body에 

raw- json으로 기입해서, 백엔드에게 보내야 한다. 

 

우리가/백엔드가 미리 만들어놓은

회원가입 함수가 잘 작동하는지 확인 (내가 걸어놓은 If 에 해당되지 않는데도 회원가입 안되면 코드 잘못 된것) 

이게 바로 아래 과정. 

회원가입 POSTMAN 등의 정상 통신 결과, 스크린샷 촬영 

postman에 회원가입 정보가 뜬다면, 

우리는 그 정보가 mysql에 뜨는지 확인해야 한다. (데이터베이스에 저장이 잘 됐는지 --- 데이터베이스 저장 코드도 썼잖니)  

로컬 데이터베이스에 저장된 유저의 계정 스크린샷 촬영

 

show table로 select all users로 

POSTMAN 등의 정상 통신 결과, 스크린샷 촬영

로그인도 마찬가지. 

 

 

자 이제 해보자, 

내 포트 번호를 치고 유저 정보 보내기 (프론트인 척)

 

 

key error 났다. name을 body에 안 썼구나 

했는데 아니였다. 

 

post를 바로 하는건가?

회원가입 됐네? 

 

로컬 데이터베이스에 저장된 유저의 계정 스크린샷 촬영은

이제 mysql로 확인 (데이터베이스에 잘 들어갔나) 

 

처음에 급해서 실수로 cd를 했다. 맞다 나 지금 mysql 하는 거지?하고 급하게 로그인 (성격 급한 사람들은.. 코딩.. 힘듭니다 ) 

근데 내가 실수로 저번에 테이블 2개 만들어서

 

어 여기 중에 어디로 들어간거지? 이거 아는 방법 있나? 

내가 코드에 뭐라고 지정한 게 있나? 

 


git hub에 내가 만든 코드를 올리자: push

 

branch가 생성이 안 됐다고, 

여기 새로운 branch 이름 치면, 아래에 create 버튼 나오고 만들면 된다. 


이후 이것저것 하다가 오류 나서..

일단 내가 여태 한 것:

 mkdir로 폴더 만들고 

cd feature/내 이름으로  가고 

git int (이제 이 폴더는 git이 관리) 

git remote [깃허브 주소] 

 

터미널에서 branch 생성하려다가, 깃허브에 가서 직접 branch를 만들었다. 

 

git status로 가서 보았더니, branch 에 들어와있었다 

remote-v로 확인해보니, branch가 잘 연결돼있었고, 

 

거기에서 git clone [내 깃허브 주소]

그리고 git status로 확인해보네, 아직 add와 commit이 안 돼있다고. 

 

하도 에러나니, 터미널에서

이렇게 힌트를 줬다. 

 

이전에 git branch feature/[ ] 로 branch 생성했고, 

git branch로 확인하니, 그전엔 아무것도 없던 게 드디어 생겼다 

그런데 내가 깃허브에 직접 생성한 branch 이름과, 여기 이름이 다른데 어떻게 된걸까

 

 

이제 드디어 git add 를 한다. 모든 걸 올릴거니까 git add . 

 


다시 복습을 한 뒤 시도★

 

복습 정리 

 

깃허브 branch 생성, remote 올리고, pull request, main branch pull 까지 : 한 사이클 정리

1) 로컬폴더 만들기 terminal에서 cd desktop > mkdir 폴더 만들고 (로컬 폴더) 깃허브 가서 new repository> create 만들고 terminal에서 git init 하고, git remote 혹은 git remote-v 하면 아무것도 안 나오는 게 정상 이

pm-developer-justdoit.tistory.com

 

이후 성공한 방법! 

 

[깃허브] branch 생성 후 github 업로드 성공!

포스팅 업로드를하다가, user- 회원가입 , 로그인 posting- 포스팅 이렇게 구분해서 코드를 미리 올려놓으면 좋겠다 싶어서, 내 개인 repository에 올리고 싶어서 다시한번 실패했던, 질문하려고 했던 g

pm-developer-justdoit.tistory.com