목록공부/node.js (56)
저장을 습관화
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/bbSWRL/btsC87PpZxg/5x3KxSXJhuVewkLcwUXvw0/img.png)
이전 게시글 : https://ctrs.tistory.com/433 NestJS - Swagger를 사용해서 API 문서 만들기 NestJS 공식 문서 swagger 관련 https://docs.nestjs.com/openapi/introduction Documentation | NestJS - A progressive Node.js framework Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, ctrs.tistory.com 공식문서 : https://docs.nestjs.com/openapi/introduction Documentatio..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/bPfbQ8/btsCZjucOhu/So3RYPC7ucVrxjjjwuVvz1/img.png)
예를 들어, 사용자의 정보가 저장되는 Users 테이블과, 사용자가 작성한 게시글이 저장되는 Posts 테이블이 존재한다고 한다. - users.entity.ts import { Column, CreateDateColumn, DeleteDateColumn, Entity, OneToMany, PrimaryGeneratedColumn, UpdateDateColumn, } from 'typeorm'; import { Posts } from '../posts/posts.entity'; @Entity({ name: 'Users' }) // DB에서 쓰일 테이블의 이름 export class Users { @PrimaryGeneratedColumn({ type: 'int', name: 'id' }) id: numb..
상황은 사용자 로그인 이후 블로그에 게시글을 작성, 조회, 수정, 삭제하는 API를 가정하며, CRUD에 필수적인 패키지 외 가드 등은 생략한다. 사용하는 DB는 MySQL이다. 0. 사용자 정보를 가져오는 데코레이터 - user.decorator.ts import { createParamDecorator, ExecutionContext } from '@nestjs/common'; // 세션 방식 로그인 export const User = createParamDecorator( (data: unknown, ctx: ExecutionContext) => { const request = ctx.switchToHttp().getRequest(); return request.user; }, ); 1. Creat..
문법 기록 하나의 메소드에서 복수의 DB를 향해 쿼리를 전송하던 도중 DB 연결 오류 등의 에러로 쿼리가 누락되는 문제를 방지하기 위함 - examples.service.ts import { DataSource } from 'typeorm'; import { Examples } from './example.entity'; @Injectable() export class ExamplesService { constructor( @InjectRepository(Examples) private examplesRepository: Repository, private dataSource: DataSource, ) {} async exampleMethod() { const queryRunner = this.dataS..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/lbIjz/btsCpcXN57g/VGblS6SLIvk7qKDlcmKdg0/img.png)
- 증상 nest.js 프레임워크에서 로그인 기능을 만들기 위해 인증 용 가드 작성 중 가드가 참조할 strategy를 작성하였으니 계속해서 401 unauthorized가 발생하는 문제 - 원인과 해결 각 구간마다 로그를 찍어서 에러가 발생하는 부분을 확인 local-auth.guard.ts import { ExecutionContext, Injectable } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; @Injectable() export class LocalAuthGuard extends AuthGuard('local') { async canActivate(context: ExecutionContext): Promise..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/bk3UPk/btsCnGCTRwY/iZnmLkExMB2yBhN5p7STD0/img.png)
메모.. nestJS에 요청이 들어올때 이에 반응하여 동작하는 기능들의 선후관계이다. 먼저 동작하는 부분에 에러가 발생했을 경우 후에 동작하는 부분까지 요청이 가지 않으니, 이 순서를 기억해둔다면 개발 중 문제가 생겼을때 원인을 찾는데에 도움이 될 것이다. 1. 요청 수신(Request) 2. 미들웨어 2-1. 전역 미들웨어 2-2. 모듈 미들웨어 3. 가드 3-1. 전역 가드 3-2. 컨트롤러 가드 3-3. 루트(경로) 가드 4. 인터셉터(컨트롤러 수행 전) 4-1. 전역 인터셉터 4-2. 컨트롤러 인터셉터 4-3. 루트 인터셉터 5. 파이프 5-1. 전역 파이프 5-2. 컨트롤러 파이프 5-3. 루트 파이프 5-4. 루트 매개변수 파이프 6. 컨트롤러 7. 서비스 (존재하지 않는 경우도 있음) 8. ..
- 증상 TypeError: Cannot read properties of undefined (reading 'config') at Object. (C:\생략\project_community\dataSource.ts:5:8) import dotenv from 'dotenv'; import { DataSource } from 'typeorm'; dotenv.config(); const dataSource = new DataSource({ // 생략 신규 프로젝트 진행 중 dataSource.ts 파일에서 dotenv의 설정 내용을 사용하지 못하는 문제가 발생 - 원인 tsconfig.json에 esModuleInterop 옵션이 설정되어 있지 않아서 발생한 문제 이 프로젝트는 nest.js 프레임워크로 개..
- 증상 [Nest] 26544 - 2023. 11. 25. 오후 11:01:36 ERROR [TypeOrmModule] Unable to connect to the database. Retrying (1)... AlreadyHasActiveConnectionError: Cannot create a new connection named "default", because connection with such name already exist and it now has an active connection session. at AlreadyHasActiveConnectionError.TypeORMError [as constructor] (C:\Users\admin\OneDrive\바탕 화면\typeorm-i..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/qFuGd/btsAAMSu8ZN/sCKjkLwZxkcxmKyjQ3GcC1/img.jpg)
- 증상 NestJS + TypeORM + Socket.io로 사용자 간의 채팅 기능 작성 중 서로의 채팅 입력 시간이 9시간 전으로 표시되는 문제 발생 /src/channel.service.ts (입력 내용을 DB에 먼저 저장하고, socket.io를 이용하여 같은 채널 사람들에게 전송함) // ... // 채팅 작성 async postChat({ url, name, content, myId }) { // 채널 조회 const channel = await this.channelsRepository .createQueryBuilder('channel') // 'alias' .innerJoin('channel.Workspace', 'workspace', 'workspace.url = :url', { url..
메모... 세션 방식 로그인에서는 서버가 재시작될 때마다 브라우저 혹은 포스트맨 등에서의 로그인이 풀리게 된다. 이유는 사전에 별다른 조치가 없없다면 세션이 서버 메모리에 저장되는데, 서버가 종료되는 순간 메모리는 증발하기 때문이다. 브라우저에서는 쿠키가 남아있지만 서버 메모리에 세션 정보가 없기 때문에 로그인이 풀리는 것이다. 이를 막기 위해서는 세션 정보를 서버 메모리에 저장하는 것이 아닌, DB나 파일과 같은 별도 공간에 저장하는 방법이 있다. 어떤 방법을 사용해도 괜찮지만, 보통 실무에서는 Redis를 사용한다고 한다. 이는 세션을 이용한 로그인에서 발생하는 현상이고, 토큰 방식 로그인에서는 서버가 재시작되더라도 로그인이 유지된다.