우리들에게 노드를 배우게 하다.Nest를 사용하여 백엔드를 구축합니다.js와 Sequelize - 제2과: 사용자 등록 제1부분
71353 단어 postgresnodebeginnersjavascript
지난주에 나는 the first lesson of the Node.js Course,를 발표했는데, 거기에서 우리는 Nest를 사용하는 프로젝트를 시작했다.js, Nest CLI, PostgreSQL 데이터베이스 및 Sequelize그 밖에 우리는 이전을 하고 데이터베이스를 구축할 방법을 강구했다.
따라서 업데이트를 원하신다면 언제든지 1과로 돌아가서 공부를 계속하거나 저희 Github. 로부터 1과 코드를 받으십시오
또한 노드에서 만든 백엔드를 비교하고 싶습니다.GoLang에서 만든 js 백엔드를 사용하여 내 친구의 Golang Course를 확인합니다.둘 다 Angular 9 Course 및 Python and AI Course 와 함께 만들어졌습니다.이 모든 것은fintech 프로그램을 구축하는 데 사용됩니다.
오늘은 Node에서 사용자 등록을 만드는 방법을 보여 드리겠습니다.js.
우리는 두 개의 모듈, 사용자와 계정을 만들 것입니다. 우리는 새로운 사용자를 만드는 기능을 구축할 것입니다. 모든 새로운 사용자는 새로운 계정을 분배할 것입니다.
물론, 예전과 같이, 우리는 당신을 위해 영상 버전을 준비했습니다!
우리 시작합시다!
1. 재구성 마이그레이션
첫 번째 단계는 우리가 지난 수업에서 한 이전을 재구성하는 것이다.우리는 반드시 표에 몇 개의 열을 추가해야 한다.그러면 이 두 테이블을 삭제하기 위해
npm run migrate down
두 번 실행합시다.1.1users.ts
파일을 열고 코드에서 다음과 같이 변경합니다.import * as Sequelize from 'sequelize';
const tableName = 'Users';
export async function up(i: any) {
const queryInterface = i.getQueryInterface() as Sequelize.QueryInterface;
queryInterface.createTable(tableName, {
id: {
type: Sequelize.INTEGER,
allowNull: false,
autoIncrement: true,
unique: true,
primaryKey: true,
},
Username: {
type: Sequelize.CHAR(200),
allowNull: false,
},
Email: {
type: Sequelize.CHAR(50),
allowNull: false,
},
Password: {
type: Sequelize.CHAR(250),
allowNull: false,
},
Salt: {
type: Sequelize.CHAR(250),
allowNull: true,
},
createdAt: {
type: Sequelize.DATE,
},
updatedAt: {
type: Sequelize.DATE,
}
});
};
export async function down(i: any) {
const queryInterface = i.getQueryInterface() as Sequelize.QueryInterface;
queryInterface.dropTable(tableName);
}
다음 코드와 유사하도록 다른 마이그레이션 파일 1.2accounts.ts
을 엽니다.import * as Sequelize from 'sequelize';
const tableName = 'Accounts';
export async function up(i: any) {
const queryInterface = i.getQueryInterface() as Sequelize.QueryInterface;
queryInterface.createTable(tableName, {
id: {
type: Sequelize.INTEGER,
allowNull: false,
autoIncrement: true,
unique: true,
primaryKey: true,
},
Type: {
type: Sequelize.CHAR(200),
allowNull: false,
},
Name: {
type: Sequelize.CHAR(200),
allowNull: false,
},
Balance: {
type: Sequelize.INTEGER,
allowNull: true,
},
UserId: {
type: Sequelize.INTEGER,
references: {
model: 'Users',
key: 'id',
},
},
createdAt: {
type: Sequelize.DATE,
},
updatedAt: {
type: Sequelize.DATE,
}
});
};
export async function down(i: any) {
const queryInterface = i.getQueryInterface() as Sequelize.QueryInterface;
queryInterface.dropTable(tableName);
}
마지막 단계는 마이그레이션을 다시 실행하는 것입니다. 따라서 데이터베이스 변경 여부를 확인하기 위해 npm run migrate up
를 사용합니다.2. 소프트웨어 패키지 설치
사용자 등록을 만들기 위해서는 추가 패키지가 필요합니다.콘솔을 열고 설치합니다
jsonwebtoken
.$ npm install jsonwebtoken
우리가 필요로 하는 또 다른 패키지는 dotenv
입니다. 설정을 만드는 데 사용됩니다.$ npm install dotenv
완성된 후에 우리는 다음 단계로 진입합시다.3. 생성합니다.환경 파일
루트 파일로 이동하여 새 파일을 만들고 호출합니다
.env
.이 파일에서 우리는 데이터베이스 설정을 이동할 것이다.DB_HOST=<YOUR_HOST>
DB_USER=<YOUR_USERNAME>
DB_PASS=<YOUR_PASSWORD>
DB_NAME=<YOUR_DB_NAME>
JWT_KEY=<YOUR_JWT_KEY>
이제 main.ts
파일에서 이 설정을 진행해야 합니다. 이따가 migrate.ts
및 database.provider.ts
파일에서 데이터베이스 설정을 변경하겠습니다.main.ts
부터 가져옵니다.env
.import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
require('dotenv').config()
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
bootstrap();
지금, 이렇게 보일지 확인하기 위해 migrate.ts
을 엽니다....
require('dotenv').config()
const sequelize = new Sequelize({
dialect: 'postgres',
host: process.env.DB_HOST,
port: 5432,
username: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_NAME,
});
...
마지막으로 database.provider.ts
파일을 엽니다.export const databaseProvider = [
{
provide: 'SEQUELIZE',
useFactory: async () => {
const sequelize = new Sequelize({
dialect: 'postgres',
host: process.env.DB_HOST,
port: 5432,
username: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_NAME,
});
sequelize.addModels([Users, Accounts]);
return sequelize;
}
}
]
다음 단계에서는 JWT 구성을 작성합니다.4.JWT 구성
src
폴더로 이동하여 config
라는 새 폴더를 만듭니다.이 설정 폴더에서 jwtConfig.ts
파일을 만들고 jwt에 옵션을 설정합니다.export const jwtConfig = {
algorithm: 'HS256',
expiresIn: '1 day',
}
우리가 지금 해야 할 또 다른 일은 JWT_키를 생성하여 .env
에 추가하는 것이다.인터넷에서 사용할 수 있는 모든 도구를 사용하거나 console 명령을 사용하여 키를 생성할 수 있습니다.
ssh-keygen -t rsa -b 2048 -f jwtRS256.key
이 파일이 준비되어 .env
파일에 추가되면 다음 단계로 넘어갑시다!5, 사용자 모듈 및 엔터티
이 단계에서 Nest CLI를 수동으로 또는 사용할 수 있는
user.module.ts
를 생성합니다.$ nest generate module modules/user
현재, 우리는 이 파일에서 다른 작업을 수행할 필요가 없기 때문에, 사용자 폴더에 다음 파일 users.entity.ts
을 만들 것입니다.이 파일에서 우리는 데이터베이스에 전달할 데이터를 설정할 것이다.import { Table, Column, Model, DataType, CreatedAt, UpdatedAt, HasMany } from 'sequelize-typescript';
import { TableOptions } from 'sequelize-typescript';
const tableOptions: TableOptions = { timestamp: true, tableName: 'Users' } as TableOptions;
@Table(tableOptions)
export class Users extends Model<Users> {
@Column({
type: DataType.INTEGER,
allowNull: false,
autoIncrement: true,
unique: true,
primaryKey: true,
})
public id: number;
@Column({
type: DataType.CHAR(200),
allowNull: false,
})
public Username: string;
@Column({
type: DataType.CHAR(50),
allowNull: false,
validate: {
isEmail: true,
isUnique: async (value: string, next: Function): Promise<any> => {
const exists = await Users.findOne({ where: { Email: value } });
if (exists) {
const error = new Error('This email is already used.');
next(error);
}
next();
}
}
})
public Email: string;
@Column({
type: DataType.CHAR(250),
allowNull: false,
})
public Password: string;
@Column({
type: DataType.CHAR(250),
allowNull: true,
})
public Salt: string;
@CreatedAt
public createdAt: Date;
@UpdatedAt
public updatedAt: Date;
}
다행이다, 이제 우리는 다음 시로 들어갈 수 있다!6. 사용자 공급자 및 인터페이스
다음으로, 우리가 지금 해야 할 일은 사용자 공급자를 만드는 것이다.사용자 폴더create
users.provider.ts
파일에서 이 파일에 다음 코드를 만듭니다.import { Users } from './users.entity';
export const UsersProviders = {
provide: 'USERS_REPOSITORY',
useValue: Users
}
완료되면 모듈을 열고 공급자를 추가합니다.@Module({
providers: [UsersProviders],
exports: [
UsersProviders,
]
})
이제 인터페이스를 만듭니다. 여기서 사용자 대상의 유형을 정의합니다.user
폴더에 새 폴더interface
를 만들고 이 폴더에 user.interface.ts
파일을 만듭니다.이 파일에서 다음 인터페이스를 만듭니다.export interface IUser {
id: number;
Username: string;
Email: string;
Password: string;
Salt: string;
Accounts: [];
}
자, 이제 우리는 이 수업의 가장 감동적인 부분을 시작할 수 있습니다. 준비되었습니까?7, 사용자 서비스 및 컨트롤러
이 때, 우리는
user.service.ts
파일을 만들 것입니다. 이 파일에서, 우리는 데이터를 데이터베이스에 저장하는 함수를 구축할 것입니다.새로 만든 파일을 열고 다음 코드를 입력하십시오.
import { Injectable, Inject } from '@nestjs/common';
import { Users } from './users.entity';
import * as jwt from 'jsonwebtoken';
import { jwtConfig } from './../../config/jwtConfig';
import crypto = require('crypto');
@Injectable()
export class UsersService {
constructor(
@Inject('USERS_REPOSITORY') private usersRepository: typeof Users,
) { }
public async create(user: any): Promise<object> {
const exists = await Users.findOne({ where: { Email: user.Email } });
if (exists) {
throw new Error('This email is already used.');
} else {
user.Salt = crypto.randomBytes(128).toString('base64');
user.Password = crypto.createHmac('sha256', user.Password + user.Salt).digest('hex');
const newUser: any = await this.usersRepository.create<Users>(user);
const jwtToken = jwt.sign(user, process.env.JWT_KEY, jwtConfig);
newUser.Token = jwtToken;
return newUser;
}
}
}
다행이다, 보아하니 이렇다!우리는 지금 컨트롤러가 하나만 필요합니다. 거기에서 단점과 API 방법을 설정할 것입니다.user.controller.ts
파일을 만들고 다음 코드를 만듭니다.import { Controller, Post, Body, HttpException, HttpStatus } from '@nestjs/common';
import { UsersService } from './users.service';
import { IUser } from './interfaces/user.interface';
@Controller('users')
export class UsersController {
constructor(private usersService: UsersService) { }
@Post('register')
public async register(@Body() user: IUser): Promise<any> {
const result: any = await this.usersService.create(user,);
if (!result.success) {
throw new HttpException(result.message, HttpStatus.BAD_REQUEST);
}
return result;
}
}
현재, 우리는 이 파일들을 모듈 파일에 주입해야 한다.@Module({
controllers: [UsersController],
providers: [UsersProviders, UsersService],
exports: [
UsersService,
UsersProviders,
]
})
보아하니 우리가 등록한 첫 번째 부분은 이미 준비가 된 것 같다. 그러면 두 번째 부분을 만들자. 우리는 모든 등록 사용자를 위해 계정을 만들 것이다.8. 계정 모듈 및 엔터티
Nest CLI를 사용하고 새 모듈을 만듭니다.
$ nest generate module modules/accounts
새 폴더에 만든 새 모듈을 보실 수 있습니다. 이전과 마찬가지로, 저희는 현재 계정 모듈 파일에서 할 일이 없습니다.그러면 accounts.entity.ts
파일을 만들고 파일이 아래의 코드처럼 보일 수 있도록 하겠습니다.import { Table, Column, Model, DataType, CreatedAt, UpdatedAt, ForeignKey, BelongsTo } from 'sequelize-typescript';
import { TableOptions } from 'sequelize-typescript';
import { Users } from '../user/users.entity';
const tableOptions: TableOptions = { timestamp: true, tableName: 'Accounts' } as TableOptions;
@Table(tableOptions)
export class Accounts extends Model<Accounts> {
@Column({
type: DataType.INTEGER,
allowNull: false,
autoIncrement: true,
unique: true,
primaryKey: true,
})
public id: number;
@Column({
type: DataType.CHAR(200),
allowNull: false,
})
public Type: string;
@Column({
type: DataType.CHAR(200),
allowNull: false,
})
public Name: string;
@Column({
type: DataType.INTEGER,
allowNull: true,
})
public Balance: number;
@ForeignKey(() => Users)
public UserId: number;
@BelongsTo(() => Users, {
as: 'Users',
foreignKey: 'UserId',
targetKey: 'id',
})
public Users: Users;
@CreatedAt
public createdAt: Date;
@UpdatedAt
public updatedAt: Date;
}
다행이다, 준비가 다 되었으니, 우리는 다음 단계를 계속할 수 있다.9. 계정 공급자와 인터페이스
이제 계정 모듈을 위한 공급자를 만듭니다.
accounts
폴더에 accounts.provider.ts
파일을 작성하십시오.이 파일에서 다음 코드 설정 공급자를 사용해야 합니다.import { Accounts } from './accounts.entity';
export const AccountsProviders = {
provide: 'ACCOUNTS_REPOSITORY',
useValue: Accounts
};
앞에서 말한 바와 같이, 우리는 인터페이스가 필요하기 때문에, interfaces
라는 새 폴더를 만들고, 이 파일에 다음과 같은 대상을 포함하는 accounts.interface.ts
파일을 만듭니다.export interface IAccount {
id: number;
Type: string;
Name: string;
Balance: number;
UserId: number;
}
우리는 계정 서비스와 컨트롤러를 만들 준비가 되어 있습니다.10. 계정 서비스 및 컨트롤러
accounts
폴더에서 accounts.service.ts
파일을 만듭니다. 이 파일에서 다음 함수를 만듭니다.import { Injectable, Inject } from '@nestjs/common';
import { Accounts } from './accounts.entity';
@Injectable()
export class AccountsService {
constructor(
@Inject('ACCOUNTS_REPOSITORY')
private accountsRepository: typeof Accounts
) { }
public async create(UserId: number): Promise<object> {
const account = {
Name: 'Account',
Type: 'Personal Account',
Balance: 100,
UserId: UserId,
}
const newAccount: any = await this.accountsRepository.create<Accounts>(account);
return newAccount;
}
}
보시다시피, 우리는 초기 사용자 계정에 하드코딩 값을 설정하고 있습니다. 기본값이기 때문에, 나중에 사용자가 변경할 수 있습니다.같은 폴더에
accounts.controller.ts
파일을 만듭니다.이 파일에 다음 코드를 입력하면 끝점에서 사용할 수 있습니다.import { AccountsService } from './accounts.service';
import { Controller, Post, Body, HttpException, HttpStatus } from '@nestjs/common';
import { IAccount } from './interfaces/accounts.interface';
@Controller('accounts')
export class AccountsController {
constructor(private accountsService: AccountsService) { }
@Post('create-account')
public async register(@Body() UserId: number): Promise<any> {
const result: any = await this.accountsService.create(UserId);
if (!result.success) {
throw new HttpException(result.message, HttpStatus.BAD_REQUEST);
}
return result;
}
}
우리는 곧 수업이 끝난다.우리는 단지 몇 개의 파일을 업데이트하고 테스트를 진행할 수 있을 뿐이다.11. UserService에 AccountsService 추가
우리는 이 함수를 사용하여 등록 함수에 계정을 만들 것입니다.그러나 우선 모듈을 업데이트해야 하기 때문에
accounts.module.ts
파일을 열어 다음 코드처럼 보일 수 있도록 합니다.@Module({
imports: [DatabaseModule],
controllers: [AccountsController],
providers: [AccountsProviders, AccountsService],
exports: [AccountsProviders, AccountsService]
})
저장한 후 다른 모듈 파일users.module.ts
을 열고 업데이트합니다.@Module({
controllers: [UsersController],
imports: [AccountsModule],
providers: [UsersProviders, UsersService],
exports: [
UsersService,
UsersProviders,
]
})
따라서 우리는 그것을 가져올 수 있다user.service.ts
.현재, 이 파일은 아래의 코드와 유사해야 한다.import { Injectable, Inject } from '@nestjs/common';
import { Users } from './users.entity';
import * as jwt from 'jsonwebtoken';
import { jwtConfig } from './../../config/jwtConfig';
import { AccountsService } from './../accounts/accounts.service';
import crypto = require('crypto');
@Injectable()
export class UsersService {
constructor(
@Inject('USERS_REPOSITORY') private usersRepository: typeof Users,
private accountsService: AccountsService,
) { }
public async create(user: any): Promise<object> {
const exists = await Users.findOne({ where: { Email: user.Email } });
if (exists) {
throw new Error('This email is already used.');
} else {
user.Salt = crypto.randomBytes(128).toString('base64');
user.Password = crypto.createHmac('sha256', user.Password + user.S
alt).digest('hex');
const newUser: any = await this.usersRepository.create<Users>(user);
const jwtToken = jwt.sign(user, process.env.JWT_KEY, jwtConfig);
newUser.Token = jwtToken;
if (newUser) {
this.accountsService.create(newUser.id)
}
return newUser;
}
}
}
알겠습니다. 계정 서비스에서create 함수를 전달했고 새 사용자가 등록할 때마다 새 계정을 만들었습니다.전체 백엔드를 작업하기 위해서, 우리는 사용자 실체와 데이터베이스 제공 프로그램을 업데이트해야 한다.사용자를 열겠습니다.실체우리는 사용자 클래스의 끝에 몇 줄의 코드를 추가할 것이다.
@HasMany(() => Accounts, 'UserId')
public Accounts: Accounts[];
이제 데이터베이스를 열어 봅시다.공급업체.ts 파일과 두 실체를 가져옵니다.가져오기가 완료되면 이를 모델로 주입합니다.import { Sequelize } from 'sequelize-typescript';
import { Users } from '../user/users.entity';
import { Accounts } from '../accounts/accounts.entity';
export const databaseProvider = [
{
provide: 'SEQUELIZE',
useFactory: async () => {
const sequelize = new Sequelize({
dialect: 'postgres',
host: process.env.DB_HOST,
port: 5432,
username: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_NAME,
});
sequelize.addModels([Users, Accounts]);
return sequelize;
}
}
]
봐라!테스트를 해볼게요!12. 테스트
나는 지금 우체부를 사용하여 우리의 API를 테스트할 것이다.만약 이 프로그램을 실행하지 않았다면,
nest start
또는 npm run start
을 사용해서 우편 배달원을 열 준비가 되었을 때 실행하십시오.다음 그림에서 내 설정을 볼 수 있기 때문에 비슷한 설정을 시도할 수 있습니다.또한 데이터베이스를 열어 데이터가 존재하는지 확인할 수 있습니다.나는 그것이 너에게 유용하길 바란다.
결론
이 과정에서, 우리는 새로운 사용자의 등록을 만들고 기본 계정을 만들 것입니다.
다음 과정에서 우리는 로그인 기능을 배울 것이다.
모든 코드를 정확하게 가져오지 못하면 Github로 이동하여 버그를 찾으십시오.
Node.js Course - Lesson 2: User registration - Code
또한 동일한 응용 프로그램GoLang backend과 전단AI for investment을 구축하고 있는 다른 과정으로 이동하는 것을 기억하십시오.
읽어주셔서 감사합니다.
둘리의 안나.
Angular 9
Reference
이 문제에 관하여(우리들에게 노드를 배우게 하다.Nest를 사용하여 백엔드를 구축합니다.js와 Sequelize - 제2과: 사용자 등록 제1부분), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/duomly/let-s-learn-node-js-by-building-a-backend-with-nest-js-and-sequelize-lesson-2-user-registration-3edp텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)