<To-Do List>
- 58~63강 강의듣기
- 일일보고 작성하기
<배운 내용 요약 정리>
58~59강 저장된 게시글을 확인하려면? GET!
1. index.js를 통해서 메인화면 구성하기
>> 원래 맨 처음에 html에서 화면을 구성했던 코드
<div class="item-list">
<div class="item-list__img">
<img src="assets/image.svg" alt="img" />
</div>
<div class="item-list__info">
<div class="item-list__info-title">블루투스 키보드 팝니다</div>
<div class="item-list__info-meta">서초동 4시간 전</div>
<div class="item-list__info-price">5,000원</div>
</div>
</div>;
>> html코드를 바탕으로 js에서 다음과 같이 구현할 수 있다.
const renderData = (data) => {
// data = [{id:1,title:'aa'...},{id:2,title:'bbb'...}..]이런형태
const main = document.querySelector("main");
data.reverse().forEach(async (obj) => {
// 배열 각각에 대해서 반복문 돌리기
// 리버스해주는 이유는 최근 작성한 것이 위에 올라오도록 하기 위해서 해줌
const itemListDiv = document.createElement("div");
itemListDiv.className = "item-list";
const itemListImgDiv = document.createElement("div");
itemListImgDiv.className = "item-list__img";
const img = document.createElement("img");
const res = await fetch(`/images/${obj.id}`);
const blob = await res.blob();
const url = URL.createObjectURL(blob);
img.src = url;
const itemListInfoDiv = document.createElement("div");
itemListInfoDiv.className = "item-list__info";
const itemListInfoTitleDiv = document.createElement("div");
itemListInfoTitleDiv.className = "item-list__info-title";
itemListInfoTitleDiv.innerText = obj.title;
const itemListInfoMetaDiv = document.createElement("div");
itemListInfoMetaDiv.className = "item-list__info-meta";
itemListInfoMetaDiv.innerText = obj.place + " " + calcTime(obj.insertAt);
const itemListInfoPriceDiv = document.createElement("div");
itemListInfoPriceDiv.className = "item-list__info-price";
itemListInfoPriceDiv.innerText = obj.price;
itemListImgDiv.appendChild(img);
itemListInfoDiv.appendChild(itemListInfoTitleDiv);
itemListInfoDiv.appendChild(itemListInfoMetaDiv);
itemListInfoDiv.appendChild(itemListInfoPriceDiv);
itemListDiv.appendChild(itemListImgDiv);
itemListDiv.appendChild(itemListInfoDiv);
main.appendChild(itemListDiv);
});
};
2. 시간기능 구현하기
- 위에까지 하고나면 우리가 작성했던 css가 있기때문에 위치에 맞춰서 글자정보들은 다 들어가 있을 것이다.
- 이제 calcTime()이라는 함수를 이용하여 시간정보를 구현해보자.
const calcTime = (timestamp) => {
// 한국시간 = UTC + 9시간
const curTime = new Date().getTime() - 9 * 60 * 60 * 1000;
const time = new Date(curTime - timestamp);
const hour = time.getHours();
const minute = time.getMinutes();
const seconds = time.getSeconds();
if (hour > 0) return `${hour}시간 전`;
else if (minute > 0) return `${minute}분 전`;
else if (seconds > 0) return `${second}초 전`;
else return "방금 전";
};
3. 이미지 불러오기
>> 서버에 get요청을 보내서 이미지 요청한 후 반환받은 값에 대해서 이미지(2진법)으로 변경하기
- 이미지는 우리가 blob(16진수)로 db에 저장을 해두었다.
- 그래서 이 blob를 자바스크립트에서 받아서 이미지로 변경하는 작업이 필요하다.
const img = document.createElement("img");
const res = await fetch(`/images/${obj.id}`);
const blob = await res.blob();
const url = URL.createObjectURL(blob);
img.src = url;
>> 서버에서 get요청을 받으면 이미지 정보를 반환하기
@app.get("/images/{item_id}")
async def get_image(item_id: int):
cur=con.cursor()
image_bytes = cur.execute(f"""
SELECT image FROM items WHERE id={item_id}
""").fetchone()[0]
return Response(content=bytes.fromhex(image_bytes),media_type="image/*")
+ 커밋방법
1. 메세지로
-> feat: //기능 구현시 작성
-> fix: //버그 수정시 작성
2. 이모지로(깃모지)
-> ✨: //기능 구현
-> 🐛: //버그 수정
-> 🚀: //배포
61강 Big Picture
>> 회원가입과 로그인 과정을 실제로 구현해보면서 살펴보기
1. 회원가입 기능 : 프론트 -> 백엔드 : 회원가입 요청하기 / 백엔드 -> DB : user 정보 저장하기
2. 로그인 기능: 프론트 -> 백엔드 : 로그인 요청하기 / 백엔드 -> DB : 조회 후 로그인되면 Access Token(JWT)을 발급
3. 로그인 유지 기능 -> 서버에 요청을 할때마다 발급받은 Access Token을 header에 넣어서 요청
4. 브라우저가 닫혀도 로그인 유지 기능 -> 로컬 스토리지 이용
62 ~ 63강 프론트엔드 회원 가입 기능 구현하기
1. 회원 가입 요청(id, password) -> 프론트엔드에서 해시를 통해 암호화해서 서버로 데이터를 보낸 후 회원가입 처리하기
>> 해시란?
- 임의의 길이의 입력 값을 고정된 길이의 출력값으로 변환하는 함수
- 동일한 입력에 대해 동일한 출력을 반환
- 프론트엔드에서 해시를 이용해 최소한의 보안장치를 한 후 백엔드로 보내줌(이때 sha-256 이용)
- https://coding.tools/sha256 sha-256에 대해서 일정길이의 문자열을 내보냄을 알 수 있음
>> 프론트엔드에 간단히 구현하기
- form (input, button)을 이용하여 html 만들기
<form id="signup-form" action="/signup" method="POST">
<div>회원가입</div>
<div>
<label for="id">아이디</label>
<input type="text" id="id" name="id" required />
</div>
<div>
<label for="password">패스워드</label>
<input type="password" id="password" name="password" required />
<!-- pssword타입으로 하면 화면에서는 안보이게 처리됨 -->
</div>
...
</form>
- 구현화면
>> .js를 통해 프론트엔드에서 해시를 통해 암호화하여 백엔드로 보내는 기능 구현
- html에서 submit버튼이 눌리면 formData를 받아와서 해시로 암호화하기(handleSubmitForm함수로 구현)
- 이때 패스워드란과 패스워드 확인란의 입력이 동일한지 안한지 checkPassword 함수로 확인
- 동일하다면 암호화한 해시를 서버에 보내고 서버에서 formData를 잘 받으면 "200"을 리턴하고 회원가입 완료메세지 띄우기
- 동일하지 않다면 오류메세지 띄우기
*이때 sha-256을 이용하기 위해서는 html의 바디 아래쪽에 다음과 같이 작성하기
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-sha256/0.9.0/sha256.min.js"></script>
* checkPassword 함수
const checkPassword = () => {
const formData = new FormData(form);
const password1 = formData.get("password");
const password2 = formData.get("password2");
if (password1 === password2) {
return true;
} else return false;
};
*handleSubmitForm 함수
const handleSubmitForm = async (event) => {
event.preventDefault();
const formData = new FormData(form);
const sha256Password = sha256(formData.get("password"));
// 폼데이터의 password내에 있는 데이터를 받아와서 sha256으로 변환
formData.set("password", sha256Password);
// formData 내에서 우리가 signup.html에서 password라고 name 지었던 것에 sha256Password를 설정하기
const div = document.querySelector("#info");
if (checkPassword()) {
const res = await fetch("/signup", {
method: "post",
body: formData,
});
const data = await res.json();
if (data === "200") {
div.innerText = "회원가입에 성공했습니다!";
div.style.color = "blue";
}
} else {
div.innerText = "비밀번호가 일치하지 않습니다.";
div.style.color = "red";
}
};
2. 백엔드 -> DB : 사용자 추가
>> .py 서버에서는 POST 요청을 받으면 아이디와 비밀번호를 입력받아 DB에 저장하는 기능 구현
- 우선 dbeaver를 통해 users 테이블 추가해주기
CREATE TABLE IF NOT EXISTS users (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
email TEXT NOT NULL,
password TEXT NOT NULL
);
- sql문을 이용하여 DB에 저장하기
@app.post("/signup") # 프론트엔드에서 폼을 통해서 post로 보냄(회원가입을 시켜달라고 요청을 보내는거니까)
def signup(id:Annotated[str,Form()],
password:Annotated[str,Form()],
name:Annotated[str,Form()],
email:Annotated[str,Form()]):
cur.execute(f"""
INSERT INTO users(id,name,email,password)
VALUES ('{id}','{name}','{email}','{password}')
""")
con.commit()
return "200"
* 입력받으면 다음과 같이 아이디와 해시로 암호화된 비밀번호가 서버에 들어옴(아이디=a, 비밀번호=123 작성했었음)
* 회원가입을 할때마다 다음과 같이 서버에 작성됨(dbeaver 데이터 사진)
<과제>
>> ERD를 이용해서 수강신청에 대해 그리기
* PK(기본키) = 각 데이터를 고유하게 식별할때, 기본 키
* FK(외래키) = 다른 테이블에 있는 기본 키를 참조해서 사용할 때, 외래 키
* 그리는 법
-> 내가 작성한 ERD
<하루를 돌아보며>
>> 오류 및 해결
- 59강에서 서버에서 get 요청을 받은 후 이미지정보를 반환하는 과정에서 아무리 강의와 똑같이해도 내 서버에서는 이미지가 띄워지지 않았다. 그래서 뭐가 문제인가 정말 한참을 고민했는데 item id의 자료형을 명시하지 않아 문제가 된 것임을 알고 수정하여 해결하였다.
- 또한 get요청을 받을때의 인자에서 item.id라고 작성을 했었는데 ' . '을 사용하면 객체로 인식을 해 오류가 생길 수도 있다는 점을 고려하여 item_id라고 수정하기도 했다.
'슈퍼코딩 부트캠프 > week3' 카테고리의 다른 글
슈퍼코딩 부트캠프 신입연수원 Week3 Day5 일일보고 (0) | 2024.07.20 |
---|---|
2024.07.11(목) 슈퍼코딩 부트캠프 신입연수원 week3 Day4 일일보고 (2) | 2024.07.13 |
2024.07.10(수) 슈퍼코딩 부트캠프 신입연수원 week3 Day3 일일보고 (0) | 2024.07.11 |
2024.07.09(화) 슈퍼코딩 부트캠프 신입연수원 week3 Day2 일일보고 (0) | 2024.07.11 |