9.0 Introduction
authentication = 유저가 누구인지 알아내는 것.
authorization = 유저가 권한이 있는지 알아내는 것.

이 섹션에서 구현할 로직
1. Phone Number Sended to Backend --> User? Login : Sign in
2. Create Token -- Connect to User with Random Number
3. Enter Phone Number(Twillo) --> User receive Token(Random Number) by SMS
4. Enter Token --> Send Token to Backend --> Token? Log the user In!

9.1 Account Logic

findUnique는 User나 null 줄것이다.
upsert

string을 number로 바꾸려면 앞에 + 붙여주면 됨.
+"123" => 123
123 + "" => "123"

Update or create records (upsert)
upsert()는 기존 데이터를 업데이트하거나 새 데이터베이스 레코드를 생성합니다. 다음 쿼리는 upsert를 사용하여 특정 이메일 주소로 사용자 레코드를 업데이트하거나, 존재하지 않는 경우 해당 사용자 레코드를 생성합니다.
출처: 사용자 sugar댓글

VSCode의 block 주석 하는 법: Shift + Alt + A or 상단메뉴 Edit -> Toggle block comment

자동으로 if문 처럼 동작하
최종 shortened버전

 

9.2 Token Logic

아래 index는 https://www.prisma.io/docs/concepts/components/prisma-schema/relations/relation-mode

9.3 Twilo Setup
9.4 Sending SMS

https://console.twilio.com/us1/develop/sms/try-it-out/send-an-sms?frameUrl=%2Fconsole%2Fsms%2Fgetting-started%2Fbuild%3Fx-target-region%3Dus1
npm i twilio
트윌로는 현재 node 16까지밖에 지원 안함.
그래서 nvm에서 노드 16으로 바꿔서 하니 잘 깔림.

 

느낌표 있으면 typescript한테 있는 타입이라고 말해주는 것.

9.5 Sending Email
npm install --save @sendgrid/mail
//아직 메일 인증되지 않아서 에러가 뜨는 것 같음
일단 넘어가자.

 

9.6 Token UI 

prisma stuio에서

User삭제하려고 하면 안됨.
User가 지워질 때, Token 물고있어서
그러면 어떻게 하냐?.( onDelete )
Cascade: 부모도 삭제해라.
SetNull: user값을 null로 둔다.
근데 여기선 그런 것은 필요없으니 Cascade로 두자.

구조분해
https://velog.io/@plu457/JavaScript-%EA%B5%AC%EC%A1%B0%EB%B6%84%ED%95%B4-%ED%95%A0%EB%8B%B9

 

9.7 Serverless Sessions
iron session을 써보자.
npm i iron-session


유저가 입력한 payload로 token을 검색하면
id:19인 튜플을 뽑아온다.

include라는 옵션을 주면, 
schema.prisma에서 정의한 릴레이션대로, 
user를 가지고 오는데 해당 모델(Token)의 userId로
참조하는 모델(User)의 id를 매칭한다.
매칭이 되면 이제
Token에 해당되는 User정보도 가져오는거지.


9.8 Profile Handler
9.9 Cleaning Code

9.10 NextAuth - 너무 매직같아서 안씀

 

'클론코딩-캐럿마켓 > 전반' 카테고리의 다른 글

11 Products  (0) 2023.01.04
10 AUTHORIZATION - SWR  (0) 2023.01.04
8 REFACTORING  (0) 2022.12.27
7 REACT HOOK FORM  (0) 2022.12.26
6 DATABASE SETUP  (0) 2022.12.26

8.0 Enter Form
별얘기없음

8.1 Form Submission
front에서 헤더를 정해주지 않으면,
req.body는 string으로 오게 됨. 그래서 
req.body.email 이런식으로 사용 못함
헤더에 Content-Type을 application/json으로 설정하면
req.body가 json형식으로 내려옴.
그래서 req.body.email 사용 가능.

 

8.2 Clean Code part One - 재밌다. fetch.then()이런거 정리 함.
8.3 Clean Code part Two 


8.4 widthHandler - 먼저 function을 어떻게 쓸지 적고 그 다음에 세부사항을 구현하는 방식이 좋다.
고차함수 = HOF(Higher Order Function) = 하나 이상의 함수를 인자로 받고, 결과로 함수를 리턴
https://medium.com/@la.place/higher-order-function-%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80-1c61e0bea79

 

8.5 Paths
import 예쁘게 하기
아래 안 예

import client from "../../../libs/server/client";
import withHandler from "../../../libs/server/withHandler";

 

1. tsconfig.json에서 baseUrl을 파입스크립트가 있는 위치(".")로해
2. paths에 @libs/* libs안의 모든 파일들, 이런식으로 정해
3. 그리고 tsconfig.json 설정 바꿨으면 서버 재시작 해야 

예쁘네

'클론코딩-캐럿마켓 > 전반' 카테고리의 다른 글

10 AUTHORIZATION - SWR  (0) 2023.01.04
9 AUTHENTICATION  (0) 2022.12.27
7 REACT HOOK FORM  (0) 2022.12.26
6 DATABASE SETUP  (0) 2022.12.26
4 TOUR OF TAILWIND -4 (Dark Mode, Just In Time Compiler )  (0) 2022.12.23

7.0 Introduction
일단 잠깐 쉬고 form만드는 짓을 해보자.
form은 너무 귀찮음.
React Hook Form package 써보자.


7.1 Making Forms Alone
npm i react-hook-form (React18)
npm i react-hook-form --legacy-peer-deps(React18이전)
일단 깔았고, 
이거 안깔고 하면 좋은 UX를 위해 할 일이 너무 많음을 보여줌.

7.2 The Register Function

//기존
export default function Forms(){
    const [username, setUsername] = useState("");
    const [email, setEmail] = useState("");
    const [password, setPassword] = useState("");
    const [formErros, setFormErros] = useState("");
    const onUsernameChange = (event:React.SyntheticEvent<HTMLInputElement>)=>{
        const {currentTarget: { value }} = event;
        setUsername(value);
    }
    const onEmailChange = (event:React.SyntheticEvent<HTMLInputElement>)=>{
        const {currentTarget: { value }} = event;
        setEmail(value);
    }
    const onPasswordChange = (event:React.SyntheticEvent<HTMLInputElement>)=>{
        const {currentTarget: { value }} = event;
        setPassword(value);
    }
    const onSubmit = (event:React.SyntheticEvent<HTMLFormElement>) =>{
        event.preventDefault();
        console.log(username,email,password)
    }
    return (
        <form onSubmit={onSubmit}>
            <input required minLength={5} value={username} onChange={onUsernameChange} type="text" placeholder="Username"/>
            <input required value={email} onChange={onEmailChange}  type="email" placeholder="Email"/>
            <input required value={password} onChange={onPasswordChange}  type="password" placeholder="Password"/>
            <input type="submit" value="Create Account"/>
        </form>
    );

}

 

input을 state에 연결해주는 것.


7.3 Validation

 

7.3 Validation part Two

가능한 validation options

7.3 Errors - Custom validation 만들기.

기본은 onSubmit, onBlur = 해당input exit하면 메시지 보여줌, onChange = input 바뀔 때마다

7.4 Extras
https://react-hook-form.com/api/useform

여기가면 많다.



// Wishes
// Less code (checked)
// Better valiation (checked)
// Better Erros(set, clear, display)
// Have full control over inputs
// Don't deal with events (checked)
// Eaiser Inputs (checked)

import { useForm } from "react-hook-form";
import { FieldError } from "react-hook-form/dist/types";

interface LoginForm {
    username: string,
    password: string,
    email: string,
    errors? : string,
}

export default function Forms(){
    const {
        register,
        handleSubmit,
        formState: { errors },
        watch,
        setError,
        setValue,
        reset,
        resetField,
    } = useForm<LoginForm>({mode: "onChange"});
    const onValid = (data: LoginForm) =>{
        console.log("I'm valid");
        // setError("errors", {message:"backend is offline sorry"})
        //fetch()같은거 하고 난 다음에
        // setError("username", {message:"Taken username"})
        // reset(); // 다 리셋하게
        resetField("password"); //password 필드만 리셋하게

    }
    const onInvalid = (errors: FieldError) =>{
        // console.log(errors)
    }
    // console.log(errors)
    // console.log(watch("email")) //하나 필드만 볼 수 있음. arg없으면 전체 봄.
    return (
        <form onSubmit={handleSubmit(onValid, onInvalid)}>
            <input
                {...register("username", {
                    required: "username is required",
                    minLength: {
                        message:"The username should be longer than 5 chars",
                        value: 5,
                    }
                })}
                type="text"
                placeholder="Username" 
            />
            {errors.username?.message}
            <input
                {...register("email", {
                    required: "email is required",
                    validate: {
                        notGmail: (value) => !value.includes("@gmail.com") || "Gmail is not allowed",
                    }
                })}
                type="email"
                placeholder="Email" 
                className={`${Boolean(errors.email) ? "bg-red-500" : ""}`}
            />
            {errors.email?.message}
            <input
                {...register("password", {
                    required: "password is required",
                })}
                type="password"
                placeholder="Password" 
            />
            <input type="submit" value="Create Account"/>
            {errors.errors?.message}
        </form>
    );
}

'클론코딩-캐럿마켓 > 전반' 카테고리의 다른 글

9 AUTHENTICATION  (0) 2022.12.27
8 REFACTORING  (0) 2022.12.27
6 DATABASE SETUP  (0) 2022.12.26
4 TOUR OF TAILWIND -4 (Dark Mode, Just In Time Compiler )  (0) 2022.12.23
4 TOUR OF TAILWIND -3 (Responsive Modifiers)  (0) 2022.12.23

5는 tailwind css라 건너 뜀
6.0 Before We Start
6.1 What is Prisma

Prisma란?
Node.js Typescript ORM(Object Relational Mapping)
번역기라고 보면 됨.
쿼리 없이 js로 DB 다룰 수 있게 해주는거.


6.2 Prisma Setsup
1. VSCode extension에서 Prisma 설치.
2. npm i prisma -D 설치
3. 명령어 바로 prisma하면안되고 npx prisma로 해야 함.
npx prisma init
그럼 prisma폴더와 .env 생김
아래 안내문구도 뜸. 저대로 해보자.

prisma/schema.prisma가서 provider를 mysql로 바꾸장

@같은 것들은 공식문서에 다 있다.

 

6.3 What is PlanetScale
serverless database platform = 데이터베이스 제공해준다.
serverless  = 서버를 우리가 유지보수 할 필요 없다는 뜻.
AWS의 RDS(관계형데이터베이스서비스)가 아님. 거기선 모든 설정 해야 함.
scale up/down다 해야 함.
MySQL-compatible = MySQL이 아님
그래서 설정을 좀 바꿔야 함. 나중에 보자.

MySQL이 아닌 이유는 얘네가 Vitess를 사용하기 때문.
Vitess는 유튜브를 scale하기 위해 구글이 만든 것
다시말해 Vitess는 대기업들이 규모에 맞게 MySQL을 scale하기 위해 쓰는 방법.
초당 수백만개의 쿼리, 수십만개의 연결, 수만개의 노드가 필요하면 scaling어렵다.
youtube,naver,slack,airbnb,twitter등에서 쓰임 ㄷㄷ
오픈 소스임.
planetscale의 가격:

planetscale은 개발자 경험이 좋음.
DB를 깃처럼 사용 할 수있다. 브랜치 따서 만들고..
downtime없이 배포 가능.
계정 만들자. 깃헙 있으면 그걸로 가입 가능.

6.4 Connecting to PlanetScale
여기 설명있음.
https://github.com/planetscale/cli

windows면 먼저 scoop설치해라.
https://scoop.sh/
파워쉘로 아래 명령 치면 됨.

> Set-ExecutionPolicy RemoteSigned -Scope CurrentUser # Optional: Needed to run a remote script the first time
> irm get.scoop.sh | iex

근데 어드민으로 해서 잘 안되면(scoop에서 보안상 이슈로 ㅊㅊ 안함.) 
아래가서 해결 책을 봐라
https://github.com/ScoopInstaller/Install#for-admin

나는 아래 명령어 돌림

 

iex "& {$(irm get.scoop.sh)} -RunAsAdmin"

다시 planetscale, 아래 명령어 쳐주면 됨

scoop bucket add pscale https://github.com/planetscale/scoop-bucket.git
scoop install pscale mysql // pscale mysql 설치 함.

그래서 VSCode의 터미널에서 psacle을 쳐보면 잘나와야 하는데

에러가난다.

windows는 powershell로만 되나보다. 얼른 맥으로 갈아타고싶다.
혹시몰라서 vscode 껐다 키니까 된다.


pscale region list를 실행해보자. 근데 로그인 안돼있어서 안됨.
로그인 하자: pscale auth login
그럼 브라우저 창이 뜨고, 터미널의 Confirmation Code가 같은지 확인 하면 됨


다시 pscale region list 실행

ap-northeast에 DB만들어보자.

pscale database create carrot-market --region ap-northeast
carrot-market이란 DB를 해당 지역에 만듦. 
터미널에 링크 뜸.

컴퓨터와 PlanetScale 사이에보안 연결 어떻게 만들까?
  connect        Create a secure connection to a database and branch for a local client
pscale connect carrot-market
위 명령어 치면 로그인 된 내 계정의 DB에 연결이 됨.
따로 id,pw 저장 할 필요 없음.

연결됨

그럼 .env 파일에 다음과 같이 넣는다.

DATABASE_URL="mysql://127.0.0.1:3306/carrot-market"

그럼 보안 tunnel이 생기는 것.

6.5 Push To PlanetScale
PlanetScale(Vitess)은 MySQL compatible이기 때문에, 추가 설정이 필요함.
Vitess는 foregin key constraint가 없다.

예:
Users DB:
id: 1 username:nico
Comments DB:
id:1 text:wow! user:(Users DB:1)//객체주소알려주는거

id5인 사람(존재하지않는 사용자)이 만약 댓글 추가 하려면, 
작성자의 정보화 함께 댓글을 달려면 맨 처음 User DB에서 id가 5인 사용자가 존재하는지 확인함.
그렇기 때문에 Users DB에 반드시 있어야 함.(MySQL,PostgresQL 에서)

근데 Vitess는 가능함. DB 분화에 특화되어있음.
그래서 댓글 생성 전에 사용자가 존재하는지 확인하지 않음.
foreign key constraint를 지원하지 않음.
그래서 저렇게 저장해도 오류 일어나지 않음.
이는 좋은게 아니야
그래서 이런 기능이 없는 Vitess가 아닌 Prisma에서 체크를 해야 함.


relationMode = prisma하면 됨.

그러면 Data 스키마를 push해보자.
npx prisma db push

Prisma Client가 생성됨!
플래닛 스케일 가면 스키마 업로드 된거 확인 가능.

6.6 Prisma Client
npx prisma studio
실행하면 DB 관리자 페이지 보임.

이걸로 DB추가도 가능

 

일단 client를 추가해보자
npm i @prisma/client
-D를 안붙인 이유는 백엔드에서 직접 이 client를 사용할 것이기 때문
=서비스에서 사용한다.
lib폴더에 client.ts만들고 아래 내용 작성

import { PrismaClient } from "@prisma/client";
export default new PrismaClient();


그럼 prismaclient만든거야
그리고 다음처럼 해보자.
npx prisma generate

노드모듈에 설치 됨.
모듈 가서 보면 내가 친 DB 스키마가 typescript로 등록 되어 있음

 

user라는 우리가 정의한 테이블을 다룰 수 있다.

BUT 
그냥 brower에서 접근 가능한 저런 파일에서 DB를 직접 조작할 수 있는 소스를 쓰면
보안에 말도안되는 결점이 되겠지.
그래서 다행이도 에러가 뜸.
nextjs 프론트엔드에서 prisma를 임포트 할 수 없다.

그렇다면 이 client를 어디서 사용해야 하나?


6.7 API Routes
보통은 백엔드 서버를 따로 만들지
근데 NextJS에서 API만들기도 가능.
pages폴더에 api폴더 만들면 됨
NextJS서버에 API가 생긴거
규칙 가능단함.

그리고 실행시키고 플래닛스케일로 오면 데이터가 생김

 

6.7 Recap
npx prisma db push
npx prisma generate = 데이터베이스에 말걸 수 있는 client 생김

4.11 Dark Mode

dark:

darkMode를 class로 하면 code 설정에 따라 = 수동

 

부모에 dark하면 자식들이 dark된다. 즉 이게 수동적으로 수정 하는 법

수정으로 할거면 html이나 body 같은 최상위 요소에 dark 클래스 추가 하면 되는거지

4.12 Just In Time compiler
tailwind 3.0전에는,
purge 작업이 필요했음. 매우 큰 css 파일에서 사용하지 않는 css의 클래스 네임을 삭제 함.
근데 이젠 css파일이 빈 상태에서 시작함.
JIT 컴파일러 사용함으로써 실시간으로 사용하려는 클래스를 생성함.
그래서 클래스끼리 조합이 가능한거다.

많은 reset들이 있는데 아래 처럼 설정해서 그럼

그러나 tailwind의 가장 좋은점은!

tailerwind에서 벗어나고 싶으면
what if I want to break free from the restrictions of taliwind?
예전엔 다음 처럼 했었어야 한다.<h1 style={{fontSize:800}}/>

근데 이제 다음 처럼 됨
text-[98213px]
text-[#000]

쩌네

근데 배경화면 이미지 할 때가 최고다.
bg-[url('/vercel.svg')]

<div className="text-[948px] bg-[url('/vercel.svg')]"></div>

클래스 네임으로 css를 한다.

아 버스기사 아저씨 운전 너무 못한다. 토할거같네

'클론코딩-캐럿마켓 > 전반' 카테고리의 다른 글

7 REACT HOOK FORM  (0) 2022.12.26
6 DATABASE SETUP  (0) 2022.12.26
4 TOUR OF TAILWIND -3 (Responsive Modifiers)  (0) 2022.12.23
4 TOUR OF TAILWIND -2 (modifiers)  (0) 2022.12.23
4 TOUR OF TAILWIND -1  (0) 2022.12.23

4.9 Responsive Modifiers

일반적으로 반응형은 Desktop먼저 생각하고 mobile로 바꾸는데,
tailwind는 모두 mobile에 먼저 적용된다.

sm은 640px 이상일 경우에 적용. MIN 시스템임. tailwind의 시스템이라기보다 그냥 min-width 적용된거임.

sm:, md:, lg:, xl:, 2xl: ...etc

4.9 Responsive Modifiers part Two - grid속

 

 

mobile에서 landscape:, portrait:

'클론코딩-캐럿마켓 > 전반' 카테고리의 다른 글

6 DATABASE SETUP  (0) 2022.12.26
4 TOUR OF TAILWIND -4 (Dark Mode, Just In Time Compiler )  (0) 2022.12.23
4 TOUR OF TAILWIND -2 (modifiers)  (0) 2022.12.23
4 TOUR OF TAILWIND -1  (0) 2022.12.23
NextJS + tailwind css Setup  (0) 2022.12.22

4.4 Modifiers

 

4.5 Transitions,
4.6 Modifiers for Lists (07:00)

4.7 Modifiers for Forms
Group modifier

위에 그룹 클래스 추가하고 아래 group: 하면

4.8 More Modifiers 
focus-within:bg-slate-800
required:border-2 border-yellow-400
invalid:border-2 border-red-400
placeholder-shown:border-2 border-red-400
disabled:, valid:

peer modifier - input의 state에 따라 다른 엘리먼트 상태 바꿀 수 있다.

CSS 선택자로

peer는 결국 ~ 셀렉터사용하는 거니까 peer 일리먼트가 먼저 와야 함.
peer-invalid같은건 그 다음 시블링으로 와야하는거지

 

:marker

file:

<p className="first-letter:text-7xl first-letter:text-purple-400">

 

4.0 Intro

utility-first css framework
클래스 많이 갖고 있는 엄청 뚱뚱한 css다.

부트스트랩이랑 다른점은뭐지?
=> 부트스트랩으로만들어진 데 가면 다 똑같음.
=> 정해진 스타일이 없고, 조합하면 다르다는거

vscode extension -> tailwind css 받으면 자동완성 됨
https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss
hover하면 tailwind의 소스도 보임

경고도 해줌


4.1 Test Drive part Two
자동완성 안되면 control + i 눌러
치다가 지워서 자동완성 또 안되면 control + space 눌러

이런 설명 보면 된다. hidden이 아닌 자식들에게 마진 top,bottom 준다.

4.2 Test Drive part Two, 4.3 Test Drive part Three

space-x, space-y 들은 tailwind의 것, 알아서 마 계산해줌

vscode에서 이모지나오게 하려면:
Windows: 윈도우+마침표
Mac: 커맨드+컨트롤+스페이스바

aspect-ratio와 width를 같이 주면 정사각형

 

+ Recent posts