44,000원
다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 해결됨Slack 클론 코딩[백엔드 with NestJS + TypeORM]
seed 생성 에러
안녕하세요. npm run seed:run 을하면 🌱 TypeORM Seeding v1.6.1 ✖ Could not load the config file! TypeORMError: No connection options were found in any orm configuration files. 이런 에러가 발생해서 제로초님 깃허브로 전부 복사해도 똑같이 해결이안되는데 이유를 혹시 아시나요? 메세지를 보면 ormconfig.ts를 못찾는거같아요. .env도 입력했고 프론트도 들어서 강의그대로 자동생성 진행했고, entities폴더도 깃허브로 바꿨어요. 그리고 package.json, ormconfig,create-initial-data 이런거 전부 복사해서 다시 해보고 경로도 맞아서 오타문제는 아닌거같은데.. forRoot()부분에 옵션을 직접 넣어보기도 하고 엔티티부분을 entities: ["entities/*.js"] 이거도 해보고 entities: ["dist/**/**.entity{.ts,.js}"] 이렇게 바꿔보기도 package.json의 typeorm부분을 "typeorm": "ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js --config src/ormconfig.ts", 이랗게 바꿔보기도 했는데 에러는 그대로 여서 잘 모르겠네용
- 해결됨Slack 클론 코딩[백엔드 with NestJS + TypeORM]
질문있습니다
const user = await this.usersRepository .createQueryBuilder('user') .where('user.email = :email', { email }) .innerJoin('user.Workspaces', 'workspace', 'workspace.url = :url', { url, }) .getOne(); 해당 코드에서 유저의 email 속성은 unique인데 InnerJoin을 한 이유가 있나요??
- 미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
소셜 로그인 질문
저는 passport-jwt를 사용하여 로그인을 구현하였는데, passport-apple 를 사용하여 소셜 로그인 구현 중에 막혔습니다. 아무리 구글링해봐도 passport-apple + nest.js 조합이 없어 해결이 되지않아 질문드립니다. 우선 제가 이해하고있는 전반적인 큰 흐름부터 맞나 의심됩니다. 1. passport-apple 을 통하여 유저 정보를 받아온 후 2. 유저에게 jwt를 발급 3. 유저는 클라이언트단(or 쿠키)에 jwt 저장 4. 이후 애플서버와는 연계없이 jwt를 이용해 제 서버만을 통하여 유저 정보를 줌. 이게 맞나 모르겠고 틀린 점이 있으면 지적해주시면 감사하겠습니다! 그리고 본 질문은 passport-apple을 통하여 어떻게 유저 정보를 받아오는지를 모르겠습니다. node.js passport-apple 공식문서를 통해 유추하며 해봤습니다 /apple.strategy.ts 파일 import { Injectable } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; import { Strategy } from 'passport-apple'; @Injectable() export class AppleStrategy extends PassportStrategy(Strategy,'apple') { constructor() { super({ clientID: process.env.APPLE_CLIENT_ID, teamID: process.env.APPLE_TEAM_ID, callbackURL: process.env.APPLE_CALLBACK_URL, keyID: process.env.APPLE_KEY_ID, privateKeyString: process.env.APPLE_KEY, //참고로 privateKeyLocation로도 해보고 // passReqToCallback: true도 넣어봤습니다. (뭔진 모르겠지만) }); } async validate(req,accessToken, refreshToken, idToken, profile, done) { console.log('req :', req); console.log('idToken :', idToken); console.log('accessToken :', accessToken); console.log('refreshToken :', refreshToken); console.log('profile :', profile); done(null,idToken) } } super에 필요객체를 넣고 validate 인자로 어떤값들이 들어오는지 하나하나 로그를 찍어보려했으나, 아예 저 부분으로 넘어가지않고 에러가 뜹니다. /auth.module.ts 파일 import { JwtStrategy } from './strategies/jwt.strategy'; import { Module } from '@nestjs/common'; import { JwtModule } from '@nestjs/jwt'; import { PassportModule } from '@nestjs/passport'; import { TypeOrmModule } from '@nestjs/typeorm'; import { User } from 'src/common/entities/user.entity'; import { AuthService } from './auth.service'; import { AuthController } from './auth.controller'; import { AppleStrategy } from './strategies/apple.strategy'; @Module({ imports: [ TypeOrmModule.forFeature([User]), PassportModule.register({ session: false }), JwtModule.register({ secret: process.env.JWT_SECRET_KEY, signOptions: { expiresIn: '60s' }, }), ], providers: [AuthService, JwtStrategy, AppleStrategy], controllers: [AuthController], }) export class AuthModule {} /auth.controller.ts 파일 import { AuthGuard } from '@nestjs/passport'; import { AuthService } from './auth.service'; import { Controller, Get, UseGuards, Req, Post, Body } from '@nestjs/common'; @Controller('auth') export class AuthController { constructor(private readonly authService: AuthService) {} @Get('/apple') @UseGuards(AuthGuard('apple')) async appleLogin() {} @Post('/apple/callback') @UseGuards(AuthGuard('apple')) async appleLoginCallback(@Req() req, @Body() body) { console.log("req : ",req) console.log('body : ',body) return 'ok'; } } 전 강의영상의 LocalAuthGuard 같은 클래스 파일을 따로 만들지 않고 바로 AuthGuard('apple')을 데코레이터에 넣어주는 식올 구현했습니다. 여기서 "도메인/auth/apple" 로 접속시 애플 로그인 화면이 뜨는 것까지는 되는데, 로그인을 후 "계속" 버튼을 누르면 서버에 이러한 500에러가 뜹니다 [Nest] 58 - 02/05/2022, 9:56:26 AM ERROR [ExceptionsHandler] Failed to obtain access token InternalOAuthError: Failed to obtain access token at AppleStrategy.OAuth2Strategy._createOAuthError (/usr/src/app/node_modules/passport-oauth2/lib/strategy.js:423:17) at /usr/src/app/node_modules/passport-oauth2/lib/strategy.js:177:45 at /usr/src/app/node_modules/passport-apple/src/strategy.js:101:13 at processTicksAndRejections (node:internal/process/task_queues:96:5) [Nest] 58 - 02/05/2022, 9:56:26 AM LOG [HTTP] 500 POST /api/auth/apple/callback - Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36 ::ffff:172.18.0.3 도무지 모르겠어서 2번째 (Post부분) @UseGuard데코레이터를 빼서 결과를 봐보니 body에 {state: '2ed****e0ed', code: 'ce23f9c72e7904******d8565b94b4a7.0.r**z.5nDn7h*******RJufk11LWQ'} 이러한 객체가 담겨옵니다. 제 예측으로는 이것이 access 토큰인것같고 이걸 다시 애플에 보내 유저정보를 받아내야하는것같은데, 코드를 어떻게 구현해야하는지 모르겠습니다... 혹시 실무에서 apple login을 어떻게 구현하셨는지, passport-apple이 안되거나 더 편한 다른방법이라도 있다면 알려주시면 정말 감사하겠습니다.
- 미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
ERROR [ExceptionsHandler] request.isAuthenticated is not a function
@UseGuards(new NotLoggedInGuard), @UseGuards(new LoggedInGuard) - 데코레이터를 회원가입과, 로그인에 각각 추가를 해주고 -> postman으로 회원가입, 로그인 할 시 에러가 발생합니다. { "statusCode": 500, "message": "Internal server error" } [Nest] 6463 - 2022. 02. 03. 오후 4:28:14 ERROR [ExceptionsHandler] request.isAuthenticated is not a functionTypeError: request.isAuthenticated is not a function 회원가입, 로그인 라우터에 @UseGuards 를 뺴고 실행 할 시 정상적으로 작동합니다. not-logged-in.guard.ts, logged. 쪽 auth 폴더쪽을 아에 삭제하고 제로초님 완성본 slack 본 auth 파일을 그대로 가져와서 실행해봤는데 계속 똑같은 에러가 발생하는 거 같습니다. 왜 에러가 발생하는 것일까요.. 또 신기한게 로그인 라우터 @UseGuards(LocalAuthGuard)는 정상적으로 동작하는 거 같습니다. NotLogged, Logged 만 실행이 안되네요.. @ApiResponse({ status: 200, description: '회원가입 성공', type: UserDto }) @ApiOperation({ summary: '회원가입' }) @UseGuards(new NotLoggedInGuard) @Post() async SignUpUser(@Body() body: JoinRequestDto) { await this.userService.SignUpUser(body.email, body.nickname, body.password) } @ApiCookieAuth('connect.sid') @ApiOperation({ summary: '로그아웃' }) @UseGuards(new LoggedInGuard) @Post('logout') async logout(@Response() res) { res.clearCookie('connect.sid', { httpOnly: true }); return res.send('ok'); }
- 미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
join보다 쿼리빌더가 더 좋은 이유는 무엇인가요??
17:39초쯤에 조인보다 쿼리빌더를 선호하신다고 하셨는데, 어떤 점에서 조인보다 쿼리빌더가 더 좋은지 궁금합니다! 또한, 조인과 릴레이션스의 차이는 무엇인지요? 릴레이션스가 약간 팝퓰레이터 같은 것인가요?? 업무가 바빠서 오래 못보다가 오랜만에 봤더니 헷갈리는데 릴레이션스-팝퓰레이트 같은것은 노릴레이션구조상 배열이 들어가니까 배열을 가져오는 것이고 조인은 교차테이블 개념으로 만들어서 가져오는것인가요? 쿼리빌더는 서브쿼리같은것인가용??
- 미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
실무적인 구성에 대한 질문입니다.
실무적으로 궁금한 게 있습니다. 일반적으로 대부분의 서비스들은 admin을 제공하는데요. react.js 를 이용해 실제 서비스용 frontend를 구현하고 nestjs를 이용해서 api backend를 만들고 두 번째 frontend 로 admin을 만들어서 2개의 프론트엔드(서비스용, 어드민용)를 동일한 backend api를 공유하여 사용하는지. 아니면 1개의 frontend에서 서비스용과 어드민용을 같이 만들고 backend는 1개를 두는지. 같은 backend를 사용할 경우 서비스용에 전체 기능을 가진 api를 사용하는 것은 혹시 위험하지는 않을지. adminbro같은 경우에는 자동화된 툴로 admin을 간편하게 사용할 수는 있지만, 실제 프로젝트에 적용하기에는 문제가 있는 것은 아닌지. 업무효율성을 고려하여 admin역시 만드는 것이 좋아 보이긴 합니다. 즉 정리하면 service용 reactjs, admin용 reactjs, backend 1 이렇게 구성이 될까요? (총3개) 아니면 서비스용 frontend, backend, 관리자용 frontend, backend 이렇게 구성하는 것이 좋을지. (총4개)
- 미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
raw 쿼리 사용법은 혹시 어디에서 볼 수 있을까요?
강의 중 성능면에서는 raw 쿼리를 권장하셨는데 강의를 들었을때 raw 쿼리에 대한 내용을 못들은거 같아서 질문드립니다.
- 미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
공식문서와 다른 이유가 뭘까요?
공식문서 npm install --save typeorm mysql 여기 npm install --save @nestjs/typeorm typeorm mysql2 공식문서를 따르지 않고 따로 하신 이유가 있을까요?
- 미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
테스트 DI 관련 질문
안녕하세요 제로초님 강의 잘 보고 많이 배웠습니다!! 항상 좋은 강의 올려주셔서 감사합니다! 다름이 아니라 마지막 UsersService 부분에서 Error: Nest can't resolve dependencies of the UsersService (UsersEntityRepository, WorkspaceMembersEntityRepository, ChannelMembersEntityRepository, ?). Please make sure that the argument Connection at index [3] is available in the RootTestModule context. Potential solutions: - If Connection is a provider, is it part of the current RootTestModule? - If Connection is exported from a separate @Module, is that module imported within RootTestModule? @Module({ imports: [ /* the Module containing Connection */ ] }) 다음과 같은 에러가 발생하게 되었습니다. constructor( @InjectRepository(UsersEntity) private usersRepository: Repository<UsersEntity>, @InjectRepository(WorkspaceMembersEntity) private workspaceMembersRepository: Repository<WorkspaceMembersEntity>, @InjectRepository(ChannelMembersEntity) private channelMembersRepository: Repository<ChannelMembersEntity>, private connection: Connection,) {} usersService의 connection 에서 문제가 발생한거 같은데 버전문제인지, Mocking 을 따로 해주는 것인지 모르겠습니다.
- 미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
this.usersService.postUsers의 파라미터
를 DTO로 하면 안되는겁니까? 쪼개서 넘기면 파라미터도 길어지고 가서 그 객체꺼 뽑아 써도 되지..않을까 싶어서요!
- 미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
nest-next 사용시에 문제점은 뭐가 있을까요?
SSR이 되는 next.js를 nestjs랑 같이 쓰면 2개의 계정을 돌릴 필요 없이 1개에서 되는 것은 매우 매력적이라고 느껴지는데요. 이렇게 했을 경우 react.js의 풀 기능을 사용 못한다거나 nest.js에서도 제약이 있다거나 해서 결국은 못 쓰게 되는 그런 일은 없을까요?
- 미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
AppModule.configure
AppModule.configure 이런 것에 대한 파라미터는 consumer다 라던지 이런 것에 대한 매뉴얼이나 설명은 어디에서 찾을 수 있을까요?코드는 이해하겠으나 이런 걸 왜 쓰는 지는 이해가 안되어 자료라도 찾아보려고 합니다.
- 미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
console.log('Listening on port ${port}');
Listening on port ${port} 그냥 이렇게 찍어 버리네요. 왜 그럴까요? WS이고 Git Bash입니다.
- 미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
createAt 컬럼이 default value가 없어서 에러가 납니다.
createAt 컬럼이 default value가 없어서 에러가 납니다. mysql을 default 값을 변경시켜야할까요 ? 제 코드에 혹시 문제가 있을까요 ? create-initial-data.ts Workspaces.ts (DB) Mysql DESC 에러 내용
- 미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
typeorm config 설정 후 빌드 에러
빌드시 아래와 같은 문제가 발생하고 있습니다. 타입에러라고 하는데 어떤 문제인지 찾아봐도 알기가 어렵습니다. 도움부탁드립니다. TypeError: Cannot read property 'config' of undefined at Object.<anonymous> (D:\Projects\SlackServer\dist\main.js:384:18) at __webpack_require__ (D:\Projects\SlackServer\dist\main.js:1787:33) at fn (D:\Projects\SlackServer\dist\main.js:1893:21) at Object.<anonymous> (D:\Projects\SlackServer\dist\main.js:223:19) at __webpack_require__ (D:\Projects\SlackServer\dist\main.js:1787:33) at fn (D:\Projects\SlackServer\dist\main.js:1893:21) at Object.<anonymous> (D:\Projects\SlackServer\dist\main.js:168:22) at __webpack_require__ (D:\Projects\SlackServer\dist\main.js:1787:33) at D:\Projects\SlackServer\dist\main.js:2697:37 at Object.<anonymous> (D:\Projects\SlackServer\dist\main.js:2699:12)
- 해결됨Slack 클론 코딩[백엔드 with NestJS + TypeORM]
하나의 게시물에 여러 개의 태그(카테고리)를 조회하고 싶습니다
현재 nestjs로 Stackoverflow와 유사한 교내 웹 개발 커뮤니티를 개발하는 학생입니다. 전체 질문글을 조회하는 기능을 개발하다가 한 가지 궁금점이 발생하여 질문하게 되었는데요! 주제넘게 설명을 드리자면 '전체 질문글 조회'는 velog나 stackoverflow와 같은 사이트의 루트페이지를 생각해주시면 될 것같습니다. 모든 질문글을 조회하는 과정에서 하나의 질문글에 여러 개의 카테고리가 저장되어 있을 경우 해당 질문글에 연관 돼있는 카테고리가 배열에 담겨 반환되는 것이 아닌 같은 질문글에 다른 카테고리를 가진 똑같은 질문글들이 조회됩니다. 즉, 다시 말해 질문글은 같지만 카테고리만 다른 데이터가 카테고리의 갯수만큼 조회됩니다..!! 이건 저희 프로젝트 erd입니다. 다음은 같이 querybuilder를 이용하여 left join을 한 코드입니다. 아래 사진은 위 querybuilder를 통해 도출된 결과입니다 위의 내용은 전체 조회에서 필요한 하나의 질문글에 대한 정보들은 조회한 사진입니다. 제가 원하는 출력 결과는 위의 카테고리가 따로 조회되는 것이 아닌 ```typescript TextRow { username: '송유현', '댓글내용': '댓글1', '제목': 'typeorm이 뭐에요', '내용': '제곧내', '좋아요': 3, '생성시간': 2021-12-21T15:00:00.000Z, '태그': [ [ '킥킥'] , ['typeorm'] ] }, ``` 의 형태로 출력하고 싶습니다..
- 미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
제로초님 nestjs vscode에서 디버깅하는 것 좀 알려주시면 감사합니다.
안녕하세요 제로초님. 강의 잘 봤습니다. 그런데 제가 vscode에서 nestjs 프로젝트를 하면서 브레이킹 포인트로 디버깅을 하고 싶은데 브레이킹 포인트가 안 먹혀서 질문드립니다. 인터넷에서 보고 launch.json 파일도 만들어서 해봤는데 계속 타입스크립트로 디버깅이 안되더라고요. 방법을 알려주시면 감사하겠습니다.
- 미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
build
제로초님 nest를 마지막에 빌드를 하는 이유는 무엇때문인가요?? 알아보려 해도 이유를 말하는 곳이 없네요....
- 미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
PickType
제로초님 에러는 아닌 데 dto를 entity를 상속하고 PickType로 가져올시 api문서에는 반영되지 않는 거 같은 데 제가 잘못한걸까요?? 물론 entity에도 ApiProperty처리 했습니다. 근데 안되길래 일단 기존 dto형식으로 바꿨습니다!
- 미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
as type과 type()의 차이가 뭔가요?
1. 타입 지정에서 as type과 type()의 차이가 뭔가요? 제가 생각하기에는 as type의 경우 여러 개의 타입을 갖고 있는 변수에 as type을 쓰면 그 순간은 지정한 특정타입으로 동작하는 것으로 알고있고, type()의 경우 해당 변수를 type으로 형변환하는 것으로 알고 있는데요. 어떤 경우에 as type을 써야하는지 type()을 써야하는 지 헷갈려서 질문드립니다. 더불어 위와 같은 내용은 구글에서 어떤 식으로 찾아보면 좋을 지 키워드도 알려주시면 감사하겠습니다. 2. 혹시 타입스크립트 시퀄라이즈에 1번과 관련된 내용의 버그 같은게 있는 건가요? 아니면 제가 놓치고 있는 부분이 있을까요? 예를 들어 시퀄라이즈 DB 조회 후 getDataValue로 가져오는 타입은 any인데, 숫자에 1000단위마다 콤마를 적용하려고 toLocaleString("ko-KR")을 사용하는 경우 Number(product?.getDataValue("price")).toLocaleString("ko-KR") // "1,234" 의 경우 잘 변환되는데, (product?.getDataValue("price") as number).toLocaleString("ko-KR") // "1234"은 올바르게 변환이 안되네요. 타입스크립트 플레이그라운드에서 간단히 테스트 했었을 때는 잘됐습니다. const test: any = 1234 console.log(Number(test).toLocaleString("ko-KR")); // "1,234" console.log((test as number).toLocaleString("ko-KR")); // "1,234"