EC2 인스턴스를 먼저 생성하고 Utuntu 에 접속했다는 가정하게 진행

 

1. apt-get update

$ sudo apt-get update

     ☞   apt : advanced package tool 는 데비안의 패키징 시스템을 관리하는 도구 모음

     ☞   apt-get : 패키지 관리 명령어로써 패키지 설치, 업데이트, 제거가 가능

     ☞   apt-cache:  : 새 패키지를 검색하는데 사용

     ☞   apt = apt-get + apt-catch 의 느낌이지만 apt-get 명령의 일부 기능을 포함하지 않고있다.

2. install mysql

$ sudo apt-get install mysql-server

 

3.  설치 확인

$ dpkg -l | grep mysql-server

     ☞  dpkg -l : 시스템에 설치된  모든 package 를 리스트로 출력

     ☞   그 중에서 mysql-server 만 찾아서 출력

ubuntu@ip-172-31-39-66:/etc/mysql/mysql.conf.d$ dpkg -l | grep mysql-server
ii  mysql-server           8.0.36-2ubuntu3   all       MySQL database server (metapackage depending on the latest version)
ii  mysql-server-8.0    8.0.36-2ubuntu3  amd64          MySQL database server binaries and system database setup
ii  mysql-server-core-8.0   8.0.36-2ubuntu3  amd64   MySQL database server binaries

 

4. net-tools 설치

$ sudo apt install net-tools

   - 설치하는 이유 -   참고링크

         네트웍관리자가 흔히 사용하는 여러 가지 기능들(명령어, 유틸리티등)을 사용하기 쉽게 모아놓은 것

          ifconfig, netstat 등과 같은 명령어를 사용가능

 

5. MySQL 실행 확인

$ sudo systemctl status mysql

- systemctl : system services 를 조작하고 운영할수 있게 해주는 명령어.

- systemctl status  서비스  : 특정 서비스의 현재 상태를 보여달라는 명령어

$ sudo netstat -tap | grep mysql

   ☞  netstat : network statistics 를 의미 -  라우팅 테이블, 연결된 네트워크 같은 것을 보여주는 유틸리티

   ☞  t :  연결된 tcp 만 보여줘

   ☞  a : 연결되고 listening 하고 있는 모든 포트를 보여줘

   ☞  p : PID 와 프로그램의 이름을 보여줘

   더 많은 netstat 사용 방법  링크

 

6. MySQL 외부 접속허용 

   - 이동해서 mysqld.cnf 를 수정

$ cd /etc/mysql/mysql.conf.d
$ sudo vi mysqld.cnf

   

- 수정 내용

bind-address = 127.0.0.1 을

bind-address = 0.0.0.0  로 수정

 

7. MySQL 접속

$ sudo mysql

 

------ 다른 방식으로 접속할 시

$ mysql -u root -p

  ERROR 1698 (28000): Access denied for user 'root'@'localhost' 발생

$ sudo mysql -u root

root 유저는 auth_socket을 이용하므로 sudo  로 접속하면 가능하다. 

 

8. 사용할 데이터베이스 생성

mysql> create database temp_database;

  - temp_database 에 사용할 db 명을 입력

  - show databases; 를 입력하면 생성된 db 확인 가능

 

9. 사용자 생성

mysql> create user 'test'@'localhost' identified by 'DB패스워드';

 - test 에 원하는 이름을 생성

-  localhost 를 % 로 하여 어느 호스트에서든 접속이 가능하도록 설정 가능

- DB패스워드에 원하는 비번 설정

 

10. 모든 권한 부여

mysql> GRANT ALL PRIVILEGES ON *.* TO 'test'@'localhost' with grant option;
mysql > flush privileges;

  - *.* : 모둔 database 를 의미  -> temp_database.* 로 지정도 가능

 - with grant option : test 라는 유저에게 준 권한을 test 유저가 다른 유저에게도 권한을 부여할 수 있음.

 - flush privileges : 변경된 사항을 바로 적용하기 위해 사용하는 명령어

  권한 확인

mysql > SHOW GRANTS FOR '사용자계정'@'호스트';

 

11. AWS EC2 인바운드 규칙에 MySQL 접속포트 추가

 

 

명령어

MySQL 시작 / 서버 재시작시 MySQL 자동 재시작

$ sudo systemctl start mysql
$ sudo systemctl enable mysql

 

사용자 조회

mysql> use mysql;
mysql> select user, host from user;

 

사용자 삭제

mysql> DROP USER [user명]@[server명];

 

비번변경 -->  버전 별로 다르다

# 5.6 이하
mysql > update user set password=password('새 비번') where user = '유저이름';

# 5.7 이상
mysql > update user set authentication_string=password('새 비번') where user = '유저이름';

# 8.x 이상
mysql > alter user '유저이름'@'localhost' identified with mysql_native_password by '새 비번';

 

 

참고자료

  1. https://velog.io/@ddeo99/AWS-EC2-ubuntu%EC%97%90-MySQL-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0
  2. https://technote.kr/32

 

설치

$ npm install --save joi

 

 

예시

// app.module.ts

import * as Joi from 'joi';

@Module({
  imports: [
    ConfigModule.forRoot({
      validationSchema: Joi.object({
        NODE_ENV: Joi.string()
          .valid('dev', 'prod', 'local', 'debug')
          .default('development'),
        PORT: Joi.number().port().default(3000),
      }),
    }),
  ],
})
export class AppModule {}

 

 

npm run start:local  를 했지만

package.json 에 아래와 같이 되었있다면

"start:local": "NODE_ENV=locla nest start --watch",

 

→ Error: Config validation error: "NODE_ENV" must be one of [dev, prod, local, debug]

 

이처럼 환경변수를 인풋으로 받고 이것이 유효한지 검사하는 기능을 하는 메소드

나중에 포트 번호와 

 

출처

https://docs.nestjs.com/techniques/configuration#schema-validation

문제:

구현을 다했는데 바디에 유저의 아이디와 비밀번호를 넣을 때

{
    "username" : "test1@test.com",
    "password" : "12345678"
}

으로 해야만 성공을 하는 데  "username" 부분을 원하는대로 수정하는 방법을 몰랐다.

 

검색을 해서 알아보니 super() 로 인해 발생한 현상  -> super 부분에서 원하는 대로 수정하여 해결

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(private readonly authService: AuthService) {
    super({
      usernameField: 'email', // 여기서 'username' 대신 'email'을 사용하도록 설정
      passwordField: 'password', // 필요하다면 여기도 바꾸는 것 가능
    });
  }
  async validate(email: string, password: string): Promise<any> {
    const user = await this.authService.validateUser(new ValidateUserRequestDto({ email, password }));
    if (!user) {
      throw new UnauthorizedException('Cannot find user');
    }
    return user;
  }
}

에러 문구

[Nest] 13029 - 05/27/2024, 1:49:37 AM ERROR [ExceptionsHandler] secretOrPrivateKey must have a value Error: secretOrPrivateKey must have a value

   - .env 파일에서 값을 불러 들이지 못하는 상황

 

에러상황 시 코드

auth.module.ts

import * as dotenv from 'dotenv';
dotenv.config();
import { forwardRef, Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { UserModule } from '../user/user.module';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy';
import * as process from 'node:process';
import { JwtStrategy } from './jwt.strategy';

@Module({
  imports: [
    JwtModule.register({
      secret: process.env.JWT_SECRET,
      signOptions: { expiresIn: '3m' },
    }),
    forwardRef(() => UserModule),
    PassportModule,
  ],
  providers: [AuthService, LocalStrategy, JwtStrategy],
  controllers: [AuthController],
  exports: [AuthService],
})
export class AuthModule {}

 

구글링을 통해서 동기화의 문제로  .env 이 호출이 되지 않은 것을 파악,

https://stackoverflow.com/questions/58673430/error-secretorprivatekey-must-have-a-value

 

Error: secretOrPrivateKey must have a value

I am using jwt to create token, but when i login via postman I get the error "Error: secretOrPrivateKey must have a value" from my console. I have attached my login code. Please anyone who can help...

stackoverflow.com

 

에 있는 답변을 따라  JwtModule.register  -> JwtModule.registerAsync 로 수정

import * as dotenv from 'dotenv';
dotenv.config();
import { forwardRef, Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { UserModule } from '../user/user.module';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy';
import { JwtStrategy } from './jwt.strategy';
import { ConfigService } from '@nestjs/config';

@Module({
  imports: [
    JwtModule.registerAsync({
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => ({
        secret: configService.get<string>('JWT_SECRET'),
        signOptions: { expiresIn: '3m' },
      }),
    }),
    forwardRef(() => UserModule),
    PassportModule,
  ],
  providers: [AuthService, LocalStrategy, JwtStrategy],
  controllers: [AuthController],
  exports: [AuthService],
})
export class AuthModule {}

 

추가적으로 

app.module.ts 에서 ConfigModule 을 global 하게 사용할 수 있도록 설정하고

TypeOrmModule 설정도 동기화 문제가 생기지 않도로 아래와 같이 설정

import * as dotenv from 'dotenv';
dotenv.config();
.....

@Module({
  imports: [
    TypeOrmModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => ({
        type: 'mysql',
        host: configService.get<string>('DB_HOST'),
        port: configService.get<number>('DB_PORT'),
        username: configService.get<string>('DB_USERNAME'),
        password: configService.get<string>('DB_PASSWORD'),
        database: configService.get<string>('DB_NAME'),
        autoLoadEntities: true,
        synchronize: true,
        logging: true,
        namingStrategy: new SnakeNamingStrategy(),
      }),
    }),
    ConfigModule.forRoot({
      isGlobal: true,
      envFilePath: `.env.${process.env.NODE_ENV}`,
    }),
    ...
  ],
  controllers: [AppController],
  providers: [AppService, ConfigService],
})
export class AppModule {}

 

envFilePath: `.env.${process.env.NODE_ENV} 이 부분은

package.json 에  개발 모드에 따라 다른 .env 를 읽어 올수 있도록 설정한 것을 반영

문제(출처: 프로그래머스)

선분 3개가 평행하게 놓여 있습니다. 세 선분의 시작과 끝 좌표가 [[start, end], [start, end], [start, end]] 형태로 들어있는 2차원 배열  lines 가 매개변수로 주어질 때, 두 개 이상의 선분이 겹치는 부분의 길이를 return 하도록 solution 함수를 완성해보세요.

 

▶ 내가 푼 방식

//내가 작성한 코드

 

 다른 유저가 푼 방식

// 유저 1
function solution(lines) {
    const start = Math.min(...lines.flat())
    const end = Math.max(...lines.flat())
    const lst = [...Array(end-start)].fill(0)    
    
    lines.forEach(el => {
        for(let i=el[0];i<el[1];i++){
            lst[i-start]+=1
        }
    })
    return lst.reduce((a,c)=> c>1 ? a+1 : a ,0)
}

 

 이 코드는 임의로 최대 길이와 같은 빈 배열을 생성

주어진 직선에 해당하는 구간에 +1 을 해주고
1 이상인 위치가 겹치는 부분이므로

1이상인 부분만 카운트해서 총 겹치는 구간의 길이를 구함  

 

     -  해당 코드 출처는 블로그 https://supersfel.tistory.com/entry/JS-%EA%B2%B9%EC%B9%98%EB%8A%94-%EC%84%A0%EB%B6%84%EC%9D%98-%EA%B8%B8%EC%9D%B4

+ Recent posts