묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
async와 await 로직을 사용해야 하는 기준을 잘 모르겠어요
비동기 로직을 호출만 하고 끝나는게 아니라 결과값을 활용해야할 때 async, await를 활용해야 한다고 이해하고 있는데요. 한가지 이해가 잘 가지 않는 부분이Auth Service에서async registerWithEmail( user: Pick<UsersModel, 'nickname' | 'email' | 'password'>, ) { const hash = await bcrypt.hash(user.password, HASH_ROUNDS); const newUser = await this.usersService.createUser({ ...user, password: hash, }); return this.loginUser(newUser); }async 함수는 결국 Promise를 반환하니까Auth Controller에서@Post('/register/email') registerByEmail( @Body('nickname') nickname: string, @Body('email') email: string, @Body('password') password: string, ) { return this.authService.registerWithEmail({ nickname, email, password, }); }async, await를 사용하지 않으면 제대로 동작하지 않을 줄 알았는데 비동기 호출의 결과인 token이 잘 반환되더라구요. 혹시 이유를 알 수 있을까요?async, await를 판단하는 강사님 만의 기준이 혹시 있으신지, 그리고 굳이 async, await가 필요 없는 곳에도 사용하게되면 성능의 차이가 생기는지도 궁금합니다.
-
해결됨[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
Follow Count Incremet & Decrement 작업하기 - 2 강의 제목과 내용이 맞지 않는 것 같습니다.
안녕하세요.강의 덕분에 많은 것을 배우고 좀 더 nestjs에 익숙해질 수 있었습니다. 그런데 Follow Count Incremet & Decrement 작업하기 - 2 강의에서 다룬 내용이 comment count 작업과 관련한 내용이었습니다. Follow Count Incremet & Decrement 작업하기 - 1 마지막에는다음 시간에 followee count 증가 감소 내용을 다룰 것이라 하셨었거 든요.강의가 누락된 것 같습니다.참고해 주세요! ㅎ좋은 강의 감사합니다. 이어지는 강의도 많이 기대됩니다. 힘내세요!
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
UpdatePostDto 관련 질문
안녕하세요 강사님! 다름이 아니라, UpdatePostDto 코드 작성하는 부분에서 의문이 생겨 질문 드립니다. UpdatePostDto의 코드를 이렇게 작성을 해주셨는데, 하단에이 부분이 왜 필요한지가 이해가 되지 않습니다. PartialType(CreatePostDto)만으로도 충분히 CreatePostDto 안에 있는 프로퍼티들을 Optional 프로퍼티들로 바꾸는거 아닌가요?? 더불어 @IsString validator같은 경우에는 엔티티에서 이미 적용을 해주었기에 더욱 필요없지 않나 싶습니다!따라서 이 두 코드는 동일한 기능을 하는 코드로 생각이 되는데, 이렇게 명시적으로 작성을 하신 이유가 있으신가 해서 여쭤봅니다. 좋은 강의 감사드립니다!
-
미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
uploads파일의 이미지 이름 한글 깨짐 질문
프론트에서 formData넣기 직전에 파일 객체를 봤을때 한글이 제대로 잘 들어가 있었는데, 이걸 보내고 multer 설정에서 받자마자 바로 destination 메서드와 filename메서드에서 file.originalname을 콘솔 로그로 확인을 해보니 이미 한글이 깨져있더라고요. 그래서 프로젝트 로컬에서 터미널로 chcp 65001 명령어로 인코딩을 utf-8로 바꿔줬는데 그래도 여전히 이미지 파일명의 한글이 깨지던데 시도해볼 다른 방법이 더 있나요?
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
getAllPost() 함수 관련 질문 드립니다.
// posts.service.ts async getAllPost() { return this.postsRepository.find(); }안녕하세요, 궁금한 사항이 있어 질문 남깁니다. 위 코드에서 find() 메서드는 Promise를 리턴하니까 service에 존재하는 getAllPost 함수는 Promise를 리턴하게 되지 않나요?해당 코드를 실제로 돌려보니 return await this.postsRepository.find() 처럼 돌아가는게 이해가 잘 안됩니다.강의에서는 "컨트롤러에서 바로 반환을 해주기 때문에 async, await을 안 붙혀도 상관이 없다" 라고 말씀해주셨는데, 음... 바로 반환을 하면 Promise가 return되어야 하지 않나란 생각이 듭니다.이 부분에 대한 부연 설명이 가능할까요?감사합니다.
-
해결됨[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
[음량 문제] 섹션 33 - Chat Entity 생성하기
음량이 작아지는 강의입니다. 코드팩토리 통합 링크https://links.codefactory.aiFlutter 강의를 구매하시면 코드팩토리 디스코드 서버 플러터 프리미엄 채널에 들어오실 수 있습니다! 디스코드 서버에 들어오시고 저에게 메세지로 강의를 구매하신 이메일을 보내주시면 프리미엄 채널에 등록해드려요! 프리미엄 채널에 들어오시면 모든 질의응답 최우선으로 답변해드립니다!
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
안녕하세요 AccessToken 관련 질문입니다.
안녕하세요 얼마전에 Access Token 관련 질문을 드렸습니다.저는 Backend 강의만 듣고 있어서 Frontend 강의가 어떻게 진행되었는지 몰라서 여쭤봅니다!현재 전역 스테이트 변수인 recoil을 사용해서 AccessToken을 저장 중 입니다.하지만 그냥 recoil만 사용할 때는 새로 고침 시 데이터가 삭제되어서 문제가 되고 있습니다.persistAtom 이라는 속성을 사용해서 상태가 유지되도록 할 수 있다는 것을 알게 되었는데 이렇게 사용할 경우 localstorage에 토큰 값이 그대로 들어가더군요.그러면 토큰 값이 그대로 노출되어서 보안상 문제가 될 것 같은데 혹시 이게 문제가 안되는지, 그대로 사용해도 되는지아니면 새로고침시 계속 token이 사라지니까 모든 컴포넌트에 useEffect를 사용해서 restoreAccessToken을 호출하도록 만들면 어떨까요?다른 방법이 있다면 방향을 알려주세요! 감사합니다.
-
미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
카카오 로그인 serializer 구현
안녕하세요 제로초님.passport-kakao를 이용해서 kakao 로그인을 구현해보고 있습니다.로그인과 회원가입 까지는 잘 되는데, serializer을 통해서 cookie가 저장되지 않습니다. kakako.strategy.tsimport { PassportStrategy } from '@nestjs/passport'; import { Strategy } from 'passport-kakao'; import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import * as _ from 'lodash'; import { AuthService } from './auth.service'; import { Platform } from 'src/entities/common/Platforms'; @Injectable() export class KakaoStrategy extends PassportStrategy(Strategy) { constructor( private readonly configService: ConfigService, private authService: AuthService, ) { super({ clientID: configService.get<string>('KAKAO_REST_API_KEY'), clientSecret: configService.get<string>('KAKAO_CLIENT_SECRET'), callbackURL: configService.get<string>('KAKAO_REDIRECT_URI'), }); } async validate(accessToken, refreshToken, profile, done) { // eslint-disable-next-line @typescript-eslint/no-unused-vars const { _json: { id, properties: { nickname, profile_image: profileImage }, kakao_account: { email }, }, } = profile; const user = await this.authService.findOrCreateUser( email, nickname, Platform.KAKAO, ); return done(null, user); } } 아래에 있는 kakao-auth.guard.ts와 kakao.serializer.ts는 로컬 로그인과 다른 점이 없을 것 같아서 그대로 썼습니다. kakao-auth.guard.tsimport { ExecutionContext, Injectable } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; @Injectable() export class KakaoAuthGuard extends AuthGuard('kakao') { async canActivate(context: ExecutionContext): Promise<boolean> { const can = await super.canActivate(context); if (can) { const request = context.switchToHttp().getRequest(); await super.logIn(request); } return true; } } kakao.serializer.tsimport { Injectable } from '@nestjs/common'; import { PassportSerializer } from '@nestjs/passport'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { AuthService } from './auth.service'; import { Users } from 'src/entities/Users'; @Injectable() export class KakaoSerializer extends PassportSerializer { constructor( private readonly authService: AuthService, @InjectRepository(Users) private usersRepository: Repository<Users>, ) { super(); } serializeUser(user: Users, done: CallableFunction) { done(null, user.id); } async deserializeUser(userId: string, done: CallableFunction) { return await this.usersRepository .findOneOrFail({ where: { id: +userId }, select: ['id', 'email', 'nickname'], }) .then((user) => { done(null, user); }) .catch((error) => done(error)); } }이처럼 작성하면, 로그인 시 세션에 쿠키가 저장되어야 하는게 아닌가요?사실 강의에서 설명해주신 내용중 이해가 잘 가지 않는 부분이 있습니다.localStrategy에서 done(null, user) -> local-auth.guard.ts에서 super.logIn(request) -> local serializer 에서 serializeUser() 을 호출한다고 말씀하셨는데, 세 가지 파일에서 LocalStrategy, LocalAuthGuard, LocalSerializer을 서로 명시적으로 연결해준적이 없음에도 불구하고 어떻게 서로 잘 알아서 호출되는지 궁금합니다.그냥 앞에 모두 Local이 붙어서, 잘 찾아서 호출되는 건가요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
ManyToMany 테이블이 자동으로 만들어지지 않습니다..
import { ProductCategory } from 'src/apis/productsCategories/entites/productCategory.entity'; import { ProductSaleslocation } from 'src/apis/productsSaleslocations/entities/productSaleslocation.entity'; import { ProductTag } from 'src/apis/productsTags/entities/productTag.entity'; import { User } from 'src/apis/users/entities/user.entity'; import { Column, Entity, JoinColumn, JoinTable, ManyToMany, ManyToOne, OneToOne, PrimaryGeneratedColumn, } from 'typeorm'; @Entity() export class Product { @PrimaryGeneratedColumn('uuid') id: string; @Column() name: string; @Column() description: string; @Column() price: number; @Column({ default: false }) isSoldout: boolean; @JoinColumn() // 1:1 연결에서는 두 테이블 중 중심을 정하는 JoinColumn을 달아주어야한다. @OneToOne(() => ProductSaleslocation) // 일대일 연결. 어떤 테이블이랑 연결될지 표기. ProductSaleslocation 테이블과 연결 할 것이다. productSaleslocation: ProductSaleslocation; // 그 때 사용되는 Column은 productSaleslocation이고 타입은 다음과 같다, FK @ManyToOne(() => ProductCategory) // many가 Product 한개인게 Category productCategory: ProductCategory; // FK @ManyToOne(() => User) user: User; @JoinTable() // ManyToMany는 둘 중 하나에 JoinTable 작성 @ManyToMany(() => ProductTag, (productTags) => productTags.products) // 상대방 입장에서 나를 볼 때 products productTags: ProductTag[]; // 객체가 여러개이기 떄문에 객체 배열타입 사용 } import { Product } from 'src/apis/products/entities/product.entity'; import { Column, Entity, ManyToMany, PrimaryGeneratedColumn } from 'typeorm'; @Entity() export class ProductTag { @PrimaryGeneratedColumn('uuid') id: string; @Column() name: string; @ManyToMany(() => Product, (products) => products.productTags) products: Product[]; }ManyToMany 설정했는데.. product_product_tags_product_tag 테이블이 자동으로 생성이 안되네요. 코드 말고 건드려줘야 할 부분이 있나요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
폴더, 파일, 함수 생성시 s붙이는 기준
product vs products 와 같이파일 및 폴더 생성시 s를 붙이는 기준이좀 해깔리는데,어디에서 설명해주셨는지 기억이 안나서질문 드립니다~답변 주시면 감사하겠습니다~1.apis 아래 1depth 폴더에는 s를 붙임apis/products 2. entities 폴더 내부 파일 s 안붙임entities/product.entity.ts 3.module.ts, resolver.ts, service.ts 에는 s붙임src/products/products.module.tssrc/products/products.resolver.tssrc/products/products.service.ts
-
해결됨[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
섹션 19 Authorization 탭 이용해서 Basic 토큰 보내기 음량 문제
음량이 갑자기 작아진 강의 입니다. 빠른 피드백 감사합니다. 코드팩토리 통합 링크https://links.codefactory.aiFlutter 강의를 구매하시면 코드팩토리 디스코드 서버 플러터 프리미엄 채널에 들어오실 수 있습니다! 디스코드 서버에 들어오시고 저에게 메세지로 강의를 구매하신 이메일을 보내주시면 프리미엄 채널에 등록해드려요! 프리미엄 채널에 들어오시면 모든 질의응답 최우선으로 답변해드립니다!
-
해결됨[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
enum 컬럼 옵션에 대한 질문합니다.
10강의 Typeorm 이론의 EnumColumn에서는 EumColumn에서는 @Column({ type : 'enum', enum : Role, default : Role.USER, }) role: Role;enum에 Role 타입을 enum : Role 이렇게 넣고 11강의 Relations강의에서 Enum Column에서는@Column({ enum : Object.values(RolesEnum), type : 'enum', default : RolesEnum.USER }) role : RolesEnum;옵션에서 enum : Object.values(RolesEnum)로 설정을 하는데 무슨 차이가 있나요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
파이널 과제도중 질문
파이널 과제중에 html이랑 css는 어느정도 다를수있게된거같은데 타이머나 인증번호쪽 js가 쫌 안되더라고요..이걸 공부를 어떻게해야할지 고민입니다파이널과제를 완벽하게 할수있을때까지 복습을해야할지..아니면 다음 커리큘럼이 js니까 일단 진도를 나가야할지 고민입니다
-
해결됨[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
where에서 이상 이하를 입력하는 방법
where : [ { id : 1, //version : 1 이건 id = 1AND version = 1; 로 된다는 의미이다. }, { version : 1 // 이땐 id = 1 OR version = 1; 로 된다. }, { profile : { id : 3 } } ],and와 or 그리고 값에 대한 조건설정은 있지만 프로퍼티에서 이상과 이하에 대한 검색은 어떻게 하나요?
-
미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
중간 테이블 질문
엔티티 작성할 때 @ManyToMany와 @JoinTable을 사용해서 중간 테이블을 설정해주고, 따로 또 ~Members엔티티를 작성해서 중간 테이블을 설정해줬는데 이게 겹치는 문제는 없나요? 워크 벤치에 생성된 중간 테이블은 하나밖에 없던데 그건 @JoinTable에 의해 생성된 중간 테이블인가요? 직접 작성한 중간 테이블인 ~Members엔티티인가요?
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
리프레시 토큰 관련 질문이 있습니다.
안녕하세요.해당 강의에 대한 질문이라기 보다 현재 우리가 구현한 인증/인가 구현 방법에 대한 질문이 있습니다. accessToken은 만료되었을 시 refreshToken을 재발급 받을 수 있도록 우리가 API를 만들었습니다. 따라서 클라이언트 측에서 accessToken 만료 시 refreshToken을 재발급하는 API를 요청하고 갱신을 할 것이라고 생각됩니다. 하지만 refreshToken을 갱신하는 API는 refreshToken이 만료되었을 시에는 리프레쉬 토큰을 갱신하지 못합니다. 이 때 사용자에게 재로그인을 시킨다는 기획이라면 문제가 없을 것 같습니다. (재로그인이라면 리프레시 토큰 갱신 API는 불필요할 것으로 생각됩니다.) 그렇다면 리프레시 토큰을 갱신하는 API는 클라이언트 입장에서 언제 호출을 해야되나요?사용자가 우리 서비스를 이용한다면 주기적으로 리프레시 토큰을 갱신하는 API를 호출하고 리프레시 토큰을 갱신을 해놔야하나요? 정답이야 없겠지만 스탠다드한 방법이 궁금합니다!
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
access token 관련 질문드립니다.
안녕하세요 강의를 다 듣고 개인 포트폴리오 제작중에 있습니다.현재 로그인 부분을 구현중인데, 포인트 충전이라던가 마이페이지 접근시, 비밀번호 변경 시 등의 경우에 인가(여기선 fetchUser)를 받아야 한다고 이해했습니다. 그러려면, 강의에선 아래 사진처럼 header에 토큰을 넣어서 보내었습니다.하지만 직접 프론트엔드를 구축해서 api 호출하려고 하니 header에 토큰을 넣어줘야 하는데, 현재 로그인시 그냥 토큰 값인 문자열을 리턴할 뿐 엑세스토큰을 저장하는 곳이 없습니다.보통 액세스토큰을 저장할 때 변수, 로컬스토리지, 세션스토리지, 쿠키 중 무엇을 가장 많이 사용하나요?섹션 13-11의 강의에서 처럼 변수에 액세스토큰을 저장하는 경우를 생각해 봤습니다. 그러면 인증하는 컴포넌트(ex: login)와 인가를 받는 컴포넌트(ex: 포인트 충전)가 다를 때 컴포넌트에서 token을 변수로 저장하더라도 다른 컴포넌트에서는 사용 못할텐데 recoil같은 라이브러리를 사용해서 전역변수로 사용해야 하는지 궁금합니다. 아래는 프론트엔드의 login 컴포넌트를 예시를 적어보았습니다. const [token, setToken] = useState(""); await axios.post("http://localhost:5656/graphql", { query: ` mutation { login(id: "${inputId}", password: "${inputPw}") } `, }) .then(res => { setToken(res.data.data.login); } }) 감사합니다.
-
해결됨Slack 클론 코딩[백엔드 with NestJS + TypeORM]
서비스 중 API 수정이 어렵다는 부분에 궁금한 점이 있습니다
7:47부터 말씀하시는 내용에 대한 질문입니다.API 설계가 잘못되었더라도 서비스 도중이면 수정하기가 어렵다고 하셨는데요.예시로 보여주신 것처럼 API 내에서 쓰이는 함수는 섣불리 건들면 안된다는건 이해가 되었습니다. 그런데 (':url/members/:id')에서 (':url/users/:id')로 고치는 것과 같이 URL 수정에는 어떤 이유로 어려움이 있는지가 궁금합니다.제가 생각하기에는 개발자가 아닌 일반적인 사용자들은 프론트엔드에서 버튼과 같은 UI를 클릭해서 이용하지, 위 URL을 전부 입력해서 사용하는 경우는 잘 없지 않을까? 라고 생각이 들거든요.혹시 같이 작업 중인 동료 개발자들에게 혼란을 줄 수 있는 이유에서일까요?
-
해결됨[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
docker로 올린 postgresql이 authentication failed만 떠요. 깃에서 가져와도 같은 현
컨테이너 올라온 것도 확인했구요.내부로 접속을해서 alter로 비번을 재설정해도 같은 현상이 지속되네요;
-
미해결[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
docker build 시 이미지 생성부분 질문
현재Docker 3 - package.json강의 듣고 질문 드립니다아래와 같이 index.js 파일을 3회 수정후, 수정할때마다 docker build 후docker images 명령어로 확인해보니이미지가 총 3번 생성 된것을 확인 할 수 있는데, express index.js 파일import express from "express" const app = express() app.get("/qqq", function (req, res) { res.send("qqq1") }) app.listen(3000) import express from "express" const app = express() app.get("/qqq", function (req, res) { res.send("qqq2") }) app.listen(3000)import express from "express" const app = express() app.get("/qqq", function (req, res) { res.send("qqq3") }) app.listen(3000)이미지 총 3번 생성질문1size가 915 mb 로 나오는데,위에 915M * 3 만큼의 용량이 내 pc 어딘가에 저장되어 용량을 차지하고 있는게 맞나요?질문2그렇다면 왜 기존 이미지를 수정하는 방식이 아닌,매번 새로운 이미지를 생성하는걸까요?지금 윈도우에 wsl Linux 설치하여 학습중인데,우클릭해서 용량을 확인할수가 없네요뒤에 해당 내용을 알려주시나요?답변 주시면 감사하겠습니다~