묻고 답해요
131만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - Part 1 NestJS Core
JWT refreshToken 쿠키
Client 에서 Refresh Token 을 localStorage 보다는 cookie 에 저장을 하는게 보안에 더 좋다는 이야기를 들었는데요. 만약에 구현을 하려고 하면 강의에서처럼 로그인 했을때 accessToken 과 refreshToken 을 함께 보내는게 아니라 이런식으로 보내면 될까요?res.cookie( 'refreshToken', refreshToken, { httpOnly: true, secure: true, sameSite: 'strict' }); return {accessToken: '엑세스 토큰'};배포 과정과 강의를 담은 Part 2는 언제 나올까요?
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - Part 1 NestJS Core
login에서 token 을 받는 이유가 있을까요?
안녕하세요.토큰시스템을 사용하도록 엔드포인트 변경하기 편을 보고 질문드립니다.보통 login api 라고 하면 token 없이 email, pw 만 받아 validation 하는 것을 목적으로 한다고 알고있는데기획에 따라 헤더의 authorization 필드를 사용한 token 로그인도 해야할 수 있다고 하셔서 궁금한점이 생겼습니다.어떤 경우에 그런 상황이 있는지 대략적인 케이스를 소개해주실수있을까요?강의 잘 보고있습니다. 감사합니다.
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
git hub 업로드가 안되서 여쭤봐요
저같은경우 윈도우를 사용하고 있는데 두가지경우가 나오질 않아서 깃허브에 확인해보니 이렇게 프리캠프는 생성이 되었는데 들어가보니 강의에서 본것처럼 파일이 업로드 되있질 않았어요..어떻게 해야할까요?
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - Part 1 NestJS Core
Guard 이론 까지 학습 후 질문
안녕하세요.1강~가드이론까지만 학습후 질문드립니다. (파이프강의에서도 안나왔고 뒤에 강의에 왠지 안나올거같아서) 클라이언트 요청이 컨트롤러까지 가면서미들 -> 가드 -> 인터셉터 -> 파이프의 단계를 거친다고 알려주셨는데nest 에서 이렇게 레이어를 나누어둔 이유, 순서가 이렇게된 이유가 있을까요?혹은 사실 하나의 레이어에서 동작하는건데 이해를 돕기위에 이런 단계를 거친다고 개념적으로만 나누어 둔것일까요?
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - Part 1 NestJS Core
폴더명에 관한 질문인데, 크게 중요하진 않을 것 같긴한데
보통 nest g resource 명령어로 생성한곳에 entity를 생성 할때 복수형으로 entities로 만드셨었는데, common resource에서는 entity 폴더로 만드신 따로 이유가 있으신걸까용?
-
미해결탄탄한 백엔드 NestJS, 기초부터 심화까지
Auth 모듈에서 JwtAuthGuard 가 아닌, JwtStrategy 를 provider 하는 이유?
import { Module, forwardRef } from '@nestjs/common'; import { AuthService } from './auth.service'; import { PassportModule } from '@nestjs/passport'; import { JwtModule } from '@nestjs/jwt'; import { CatsModule } from 'src/cats/cats.module'; import { JwtStrategy } from './jwt/jwt.strategy'; @Module({ imports: [ PassportModule.register({ defaultStrategy: 'jwt', session: false }), JwtModule.register({ secret: 'secret', signOptions: { expiresIn: '1y' }, }), forwardRef(() => CatsModule), ], providers: [AuthService, JwtStrategy], exports: [AuthService], }) export class AuthModule {} auth.module.ts 에서 JwtAuthGuard를 provider 에 추가하지 않고, JwtStrategy를 제공하는 이유가 궁금합니다. 실제로 Cat controller 에서는 authService의 JwtAuthGuard를 통해 호출되는거 아닌가요? JwtAuthGuard & JwtStrategy 둘다 provider 에 추가하라고 하면 그것대로 이해가 되는데, JwtStrategy만 추가하는게 이해가 잘 안되어서요ㅠㅠ
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - Part 1 NestJS Core
nest에서 throw시
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요. 강의 너무 잘보구있습니다!!다름아니라 강의를 보던중 예외가 발생하면 throw new nest에서 제공되는 예외처리 이렇게 반환을 해주고있습니다. 그런데 제가 알고있는 부분으로는 throw시 그 함수가 즉시 중단되고 호출한 부분에서 try catch를 해줘야한다고 알고있었습니다. 그런데 강의에서도 그렇고 제가 직접해보았을때 그런 처리없이 postman으로 요청시 예외처리가 정상적으로 됩니다. 이게 어떤 흐름으로 되는것일까요?코드팩토리 통합 링크https://links.codefactory.aiFlutter 강의를 구매하시면 코드팩토리 디스코드 서버 플러터 프리미엄 채널에 들어오실 수 있습니다! 디스코드 서버에 들어오시고 저에게 메세지로 강의를 구매하신 이메일을 보내주시면 프리미엄 채널에 등록해드려요! 프리미엄 채널에 들어오시면 모든 질의응답 최우선으로 답변해드립니다!
-
해결됨[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - Part 1 NestJS Core
프론트엔드에서 토큰을 받아왔을 때 어디에 저장해 두는 것이 좋은가요?
Access Token이나 Refresh Token을 서버에서 받아왔을 때 로컬 스토리지에 토큰들을 저장해 놓고 사용해도 괜찮은가요..?
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - Part 1 NestJS Core
JwtStrategy 사용 vs 강의에서 말씀해주신 JwtService 만을 사용한 방법
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.코드팩토리 통합 링크https://links.codefactory.aiFlutter 강의를 구매하시면 코드팩토리 디스코드 서버 플러터 프리미엄 채널에 들어오실 수 있습니다! 디스코드 서버에 들어오시고 저에게 메세지로 강의를 구매하신 이메일을 보내주시면 프리미엄 채널에 등록해드려요! 프리미엄 채널에 들어오시면 모든 질의응답 최우선으로 답변해드립니다! 안녕하세요 강사님. 좋은 강의를 만들어 주셔서 감사합니다. 다름이 아니라 JWT 인증에 대해서 궁금한 점이 있는데요 .강의에서는 JwtService 객체에서 제공해주는 함수를 활용하여 서비스 로직을 만든 후 이를 이용해 별도의 가드를 만들어 인증을 해주는 방식을 설명해주신걸로 이해했습니다. 그러나 인터넷 검색을 해봤을 떄 JwtStrategy 를 상속 받아서 local 전략과 token 전략을 구분하여 가드를 작성하고, 이를 사용하는 방식도 있는것으로 확인했습니다. 이 두가지 방법중에 서로의 장단점과 현업에서는 어떤 방식을 더 선호하는지 질문드립니다. 감사합니다.
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - Part 1 NestJS Core
Refresh token 과 Access token 의 차이점
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.코드팩토리 통합 링크https://links.codefactory.aiFlutter 강의를 구매하시면 코드팩토리 디스코드 서버 플러터 프리미엄 채널에 들어오실 수 있습니다! 디스코드 서버에 들어오시고 저에게 메세지로 강의를 구매하신 이메일을 보내주시면 프리미엄 채널에 등록해드려요! 프리미엄 채널에 들어오시면 모든 질의응답 최우선으로 답변해드립니다! 안녕하세요 강사님, Refresh token 과 Access token 의 차이 점은 아래 두개만 있는걸로 이해하면 될까요?만료 시간사용처 (access token 은 데이터 접근시, refresh token 은 access token 발급 시에 사용) 그 외에 인증 방식, payload data, 관리 방식은 모두 동일하다고 이해하면 될까요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
상품수정 API 질문
상품 수정 api 질문합니다. 지금 보시면 update에는 async,await가 붙어있는데 데이터베이스를 거쳐 resolver로 가져오면 굳이 안붙어도 된다고 하셨는데 왜 붙어있는지 궁금합니다async update( {product,updateProductsService }:IProductsServiceUpdate):promise<Product> { const product=await this.findOne({productId}) this.checkSoldout({product}) }
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
조회 시, select로 일부 필드만 가져올 때 GraphQL 처리
안녕하세요 :)아래 코드와 같이 상품 조회할 때 select를 통해 일부 필드만 가져오도록 해봤습니다.service의 findAll 메서드에서는 유틸리티 타입으로 반환하도록 하였고,resolver에서는 Query 데코레이터에 GraphQL에서 제공하는 PickType으로 반환하게 했는데, 에러가 발생합니다.. (적절한 값이 아니라는 에러 내용)이런 상황에서는 메서드 반환 타입과 GraphQL 타입 처리를 어떻게 해주는 것이 좋은지 감이 잘 안 잡혀서 질문드려요! // products.resolver.ts @Query(() => [PickType(Product, ['id', 'name', 'description'])]) fetchProducts(): Promise<Pick<Product, 'id' | 'name' | 'description'>[]> { return this.productsService.findAll(); }// products.service.ts findAll(): Promise<Pick<Product, 'id' | 'name' | 'description'>[]> { return this.productsRepository.find({ select: ['id', 'name', 'description'], }); }
-
해결됨[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - Part 1 NestJS Core
섹션 26. 이미지 업로드 - 클래식 방법에서 질문이 있습니다!
안녕하세요!이미지 업로드 클래식 방법을 듣다 막히는 부분이 있어 질문 드립니다! @Post() @UseGuards(AccessTokenGuard) @UseInterceptors(FileInterceptor('image')) postPosts( @User('id') userId: number, @Body() body: CreatePostDto, @UploadedFile() file?: Express.Multer.File, console.log(userId); return this.postsService.createPost(userId, body, file?.filename); }컨트롤러에 해당 셋팅까지 마무리하고 postman으로 요청을 보내려고 시도를 했습니다. 하지만 400에러가 발생하더라고요 ㅠㅠ에러 message는 "Multipart : Malformed part header" 라고 표출이 됩니다. postman의 헤더 설정 문제인가해서 header셋팅하는 쪽 살펴보니 자동으로 header 설정이 되고 있어서 문제는 없는 것 같습니다.. 일단 컨트롤러에 요청자체가 걸리지 않는 것 같습니다ㅠ혹시 어떤 이유 일까요?
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - Part 1 NestJS Core
청개구리 기질로 npm을 쓰는 분들을 위한 launch.json 파일 공유
청개구리 기질로 npm으로 하고 싶어서 강의를 따라오다 여기서 막혀서 구글링 삽질로 해결 했던 정보를 공유 해요~// launch.json{ // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "type": "node", // 세팅의 타입 "request": "launch", // launch 실행하는거, attach 실행되있는거에 붙는거 "name": "Debug NestJS", // 어떤 이름으로 부를건지 "runtimeExecutable": "npm", // 어떤걸로 실행 할건지 node, yarn ... "runtimeArgs": ["run", "start:debug"], // npm run start:dev 에서 npm이 runtime이고 run start:dev가 Args임 "console": "integratedTerminal", // intergratedTerminal은 vscode에서 실행하는 터미널임 "restart": true, // 자동 연결 할건지 "port": 9229, "autoAttachChildProcesses": true // 디버거를 자동으로 process에 붙을지 말지 결정 } ] }
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - Part 1 NestJS Core
vscode의 디버거를 덕분에 알게 되었는데
강의를 다 보고 나니 너무 좋은 기능인것 같고, 실제로 해당 기능을 개발 단계에서 사용 할때는 따로 winston이나 내장 logger나 console.log 필요 없이(production에선 사용) 해당 디버거를 이용해서 하는게 훨씬 좋아 보이는데, 실무에서도 자주 사용 하시나요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
상품 등록 API 오류 납니다
ERROR [TypeOrmModule] Unable to connect to the database Retrying (2)... QueryFailedError: Incorrect datetime value: '0000-00-00 00:00:00' for column 'meetingTime' at row 1라고 오류납니다 product.resolver.tsimport { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; import { ProductsService } from './product.service'; import { CreateBoardInput } from '../boards/dto/create-board.input'; import { CreateProductInput } from './dto/create-product.input'; import { Product } from './entities/product.entity'; @Resolver() export class ProductsResolver { constructor( private readonly productsService: ProductsService, // ) {} @Query(() => [Product]) fetchProducts(): Promise<Product[]> { return this.productsService.findAll(); } @Query(() => Product) fetchProduct( @Args('productId') productId: string, // ): Promise<Product> { return this.productsService.findOne({ productId }); } @Mutation(() => Product) createProduct( @Args('createProductInput') createProductInput: CreateProductInput, ): Promise<Product> { // << 브라우저에 결과 보내주는 2가지 방법>> // 1. 등록된 내용이 담긴 객체를 그대로 브라우저에 보내주기 return this.productsService.create({ createProductInput }); // 이걸 선호. 조회 api 요청을 안해도 된다 // 2.결과에서만 간단히 보내주기 // return '정상적으로 상품이 등록되었습니다' } } product.service.tsimport { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; import { ProductsService } from './product.service'; import { CreateBoardInput } from '../boards/dto/create-board.input'; import { CreateProductInput } from './dto/create-product.input'; import { Product } from './entities/product.entity'; @Resolver() export class ProductsResolver { constructor( private readonly productsService: ProductsService, // ) {} @Query(() => [Product]) fetchProducts(): Promise<Product[]> { return this.productsService.findAll(); } @Query(() => Product) fetchProduct( @Args('productId') productId: string, // ): Promise<Product> { return this.productsService.findOne({ productId }); } @Mutation(() => Product) createProduct( @Args('createProductInput') createProductInput: CreateProductInput, ): Promise<Product> { // << 브라우저에 결과 보내주는 2가지 방법>> // 1. 등록된 내용이 담긴 객체를 그대로 브라우저에 보내주기 return this.productsService.create({ createProductInput }); // 이걸 선호. 조회 api 요청을 안해도 된다 // 2.결과에서만 간단히 보내주기 // return '정상적으로 상품이 등록되었습니다' } } productSaleslocation.entity.tsimport { Field, Float, ObjectType } from '@nestjs/graphql'; import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'; @Entity() @ObjectType() export class ProductSaleslocation { @PrimaryGeneratedColumn('uuid') @Field(() => String) id: string; @Column() @Field(() => String) address: string; @Column() @Field(() => String) addressDetail: string; // // 9자리 중에서 6자리가 소수점 @Column({ type: 'decimal', precision: 9, scale: 6 }) @Field(() => Float) lat: number; @Column({ type: 'decimal', precision: 9, scale: 6 }) @Field(() => Float) lng: number; @Column() @Field(() => Date) meetingTime: Date; } meetingTime graphlql 타입을 맞게 해났는데 왜 오류나는지 모르곘습니다
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - Part 1 NestJS Core
3분50초쯤에 오버라이드라고 말씀 하셨는데
Column().d.ts에서 declare로 정의 되어 있는것들을 오버라이드라고 말씀 하셨는데, 인자값에 따라 다른 호출을 하는건 오버로딩이 아닌가해서요!
-
미해결탄탄한 백엔드 NestJS, 기초부터 심화까지
Schema에서 DTO로 상속하는 과정에서 Decorator와 required 초기화 관련 질문입니다.
안녕하세요, 강의에서는 Cat 클래스에서 정의한 스키마를 이용해 requestDTO, responseDTO 등으로 상속해서 확장하셨습니다. 검색해보니 이때 원래 파일에 있던 Decorator 등의 메타데이터는 그대로 남아있다고 하는데요, Response 상황에서 어차피 Validation이나 API Property 같은 내용을 신경쓰지 않아도 되니까 상속해도 별 문제가 없긴할거고 강의에서도 그 부분은 크게 신경쓰지 않으신것 같습니다. 혹시 현업에서나 개발 과정에서 저렇게 PickType으로 기존 클래스를 재사용하는 과정에서 기존 클래스에 있던 여러 Decorator 들을 초기화하고 다시 세팅하려면 어떻게 해야할까요? PartialType으로 래핑하는 방법을 사용하면 required 필드는 사라집니다.상속을 하니까 API 문서에 표시되는 순서가 id가 가장 나중에 표시가 됩니다. 순서를 바꾸는 방법을 찾지못했는데 방법이 있을까요?그래서 저는 아예 schema 파일에 id까지 넣은 후에 PickType에서 id 까지 가져오는 방법을 사용해봤습니다.
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
return false 대신 try catch
function TokenAPI(phNumber){ try { checkPhoneState(phNumber); //휴대폰 상태 점검 } catch (error) { console.log(error); } const token = createToken(); //토큰발급 sendToken(phNumber,token); //휴대폰에 토큰 발송 } function checkPhoneState(phNumber){ if(phNumber.length != 11){ throw new Error("올바르지 않은 번호입니다."); } else if(isNaN(phNumber) != false){ throw new Error("올바르지 않은 번호입니다."); } } function createToken(){ return String(Math.floor(Math.random() * 1000000)).padStart(6,"0"); } function sendToken(phNumber,token){ console.log(phNumber + "번호로 인증번호 " + token + "이 전송되었습니다."); } 이런식으로 try catch 써도 되나요?
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - Part 1 NestJS Core
common.service 의 cursorPaginate 일반화 할때 nextUrl 생성시 질문입니다.
common.service 의 cursorPaginate 일반화 관련 질문입니다.nextUrl 생성할 때 아래와 같이 searchParams 를 생성하는데 이 부분은 일반화 할 수없는건가요?if (nextUrl) { for (const key of Object.keys(dto)) { if (dto[key]) { if ( key !== 'where__id__more_than' && key !== 'where__id__less_than' ) { nextUrl.searchParams.append(key, dto[key]); } } } let key = null; if (dto.order__createdAt === 'ASC') { key = 'where__id__more_than'; } else { key = 'where__id__less_than'; } nextUrl.searchParams.append(key, lastItem.id.toString()); }