테이블 정의 및 데이터베이스 설계
## 사용자 관리 테이블 설정
- [x] **사용자 테이블 (Users)**: 사용자의 기본 정보와 계정 관리를 위한 테이블을 생성합니다.
- `id`, `email`, `password`, `username`, `profile`, `bio`, `role`, `created_at`, `updated_at` 필드 추가
import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn } from 'typeorm';
export interface UserModel {
id: number;
username: string;
email: string;
password: string;
bio: string;
profile: string;
role: number;
createdAt: Date;
updatedAt: Date;
}
@Entity('users')
export class User {
@PrimaryGeneratedColumn('increment')
id!: number;
@Column({ type: 'varchar', length: 100 })
username!: string;
@Column({ type: 'varchar', length: 200, unique: true })
email!: string;
@Column({ type: 'varchar', length: 255 })
password!: string;
@Column({ type: 'varchar', length: 255, nullable: true })
bio!: string;
@Column({ type: 'varchar', length: 255, nullable: true })
profile!: string;
// 권한 ( 0: 일반 사용자, 1: 관리자 )
@Column({ type: 'int2', default: 0 })
role!: number;
@CreateDateColumn()
createdAt!: Date;
@UpdateDateColumn()
updatedAt!: Date;
}
Bcrypt
import bcrypt from 'bcryptjs';
// 비밀번호 암호화
export const hashPassword = ({password}:{password: string}) => {
const salt = bcrypt.genSaltSync(10); // salt 생성
return bcrypt.hashSync(password, salt); // 암호화된 비밀번호 반환
};
// 비밀번호 비교
export const comparePassword = ({password, hashedPassword}:{password: string, hashedPassword: string}) => {
return bcrypt.compareSync(password, hashedPassword);
};
Multer 프로필 이미지 업로드
// 이미지 파일 처리 미들웨어
const imageStorage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, path.join(__dirname, '../media/user_profile'));
},
filename: (req, file, cb) => {
const timestamp = Date.now();
const uniqueName = `${timestamp}-${file.originalname}`;
cb(null, uniqueName);
}
});
# multer 설정
export const uploadImage = multer({
storage: imageStorage,
fileFilter: imageFilter,
limits: { fileSize: 5 * 1024 * 1024 } // 예: 이미지 파일 크기 제한 5MB
});
- destination : 업로드된 파일을 저장할 폴더/디렉토리 정의
- filename : 저장될 파일의 이름을 설정해줌
파일 저장 흐름
- 클라이언트가 이미지 파일을 업로드하면, 이 미들웨어가 호출
- destination 콜백을 통해 파일이 저장될 디렉터리가 지정
- filename 콜백을 통해 파일 이름이 설정
- 설정된 파일 경로와 이름으로 서버 디스크에 저장
API 설계
Controller
// @route put /users/
// @body { username, email, password, profile }
export const signUp = async (req: Request, res: Response) => {
try {
const { username, email, password } = req.body;
const profile = req.file?.filename;
const createdUser = await signUpService({username, email, password, profile});
responseSuccess(res, createdUser, 'User created successfully', 201);
return
} catch (error) {
if (error instanceof Error) {
responseError(res, error.message, 'Failed to create user', 400);
return
}
responseError(res, 'Internal Server Error', 'Failed to create user', 500);
return
}
}
- 사용자 회원가입 시에 프로필 이미지가 있을 수 있고 없을 수 있는데 이를 Service Props에서 NULL이 가능한 상태로 허용하고 프로필 이미지 데이터가 있다면 DB에 저장하는 방식을 사용
Service
export const signUp = async (signUpProps : SignUpProps) => {
try {
const existingUser = await userRepository.findOne({
where: [
{ username: signUpProps.username },
{ email: signUpProps.email }
]
});
if (existingUser) {
throw new Error('User already exists');
}
// Hash password
const hashedPassword = hashPassword({password: signUpProps.password});
// Create new user
const newUser = userRepository.create({
...signUpProps,
password: hashedPassword
})
// Save user to database
return await userRepository.save(newUser);
} catch(error) {
if (error instanceof Error) {
throw new Error(error.message);
}
throw new Error('Internal Server Error');
}
}
- 사용자 회원가입 시에는 동일한 username 혹은 email로 가입한 계정이 있다면 동일한 사용자가 있다는 문구로 400 반환
- 비밀번호를 데이터베이스에 저장 시에는 평문으로 저장하면 보안에 대한 고려사항이 없다는 것과 동일하기에 bcrypt를 사용하여 비밀번호 암호화
Route
import express from 'express';
// Utils
import { uploadImage } from '../utils/multer';
// Controller
import { signUp } from '../controllers/userController';
const router = express.Router();
// signUp
router.post('/', uploadImage.single('profile'), signUp);
export default router;
- 회원가입 시에 사용자가 프로필 이미지를 업로드 할 수 있도록 Multer 미들웨어 추가
핵심 요약
- typeORM을 활용하여 데이터베이스 설계 ( 자동 마이그레이션 )
- 사용자 회원가입 시에 / 프로필 이미지를 Multer로 처리 ( 이미지가 있을 시에 특정 폴더에 저장하는 방식 )
- 사용자 회원가입 시에 / 사용자가 입력한 데이터로 / 회원가입을 했었던 / 다른 사용자가 있는 지 확인
'Nodejs' 카테고리의 다른 글
NodeJS 로그아웃 기능 구현 (1) | 2024.12.20 |
---|---|
NodeJS 로그인 기능 구현 (0) | 2024.12.20 |
Postgresql TypeORM으로 마이그레이션 하기 (0) | 2024.12.19 |
Nodejs PostgreSQL 연동 (1) | 2024.12.18 |
JWT, Bcrypt 예제 (0) | 2024.12.18 |