728x90
반응형

지금까지 구현했던 회원가입창에 모든 데이터를 넣고 회원가입은 완료시켜보자.

 

회원가입을 눌렀을 경우 실행되는 함수는 submitHandler이다. 다음과 같이 수정해주자.

    const submitHandler = (event : any) => {
        event.preventDefault();
        if(!userState.idDuple) {
            alert('아이디 중복여부를 체크해주세요.');
        }else {
            if(!userState.emailDuple) {
                alert('이메일 중복여부를 확인해주세요.');
            }else {
                if(!userState.emailAuth) {
                    alert('이메일 인증을 확인해주세요.');
                }else {
                    if(userState.userInfo.pw.length < 4) {
                        alert('비밀번호를 4자이상 입력해주세요.')
                    } else {
                        if(userState.userInfo.pw !== pwdCertText) {
                            alert('비밀번호와 비밀번호 확인 문자가 다릅니다.')
                        }
                        else {
                            // signup dispatch
                        }
                    }
                }
            }
        }
    }

 

지금까지 실행했던 것들로 인증을 하고 만약 다를경우 alert창을 띄워줄 것이다

 

이제부터 액션을 만들고 주석처리된 부분에 dispatch를 실행할 것이다. 액트와 타입을 지정해준다.

 

userAct.interfaces.ts

(...)

USER_SIGNUP = "USER_SIGNUP", // 회원가입

(...)

export type ActionsUser = UserInit | UserState | UserInfo | UserIdDuplicate
                         | UserEmailDuplicate | UserEmailSend | UserEmailCert
                         | UserSignup

(...)

export interface UserSignup {
    type : actionTypesUser.USER_SIGNUP;
    payload : any;
}

 

이번엔 리듀서 부분을 수정해준다.

 

user_reducer.ts

        case actionTypesUser.USER_SIGNUP:
                return {
                    ...state, data : action.payload
                }

 

 

클라이언트에서 사용할 dispatch 액션을 정의해준다. post메소드로 데이터를 전송할 것이다.

interfaces에서 userInfo 클래스를 가져오고 다음 함수를 만들어주자.

 

user_action.ts

export async function userSignup (userInfo : UserInfo) {
    const request = Axios.post('/api/user/signup',{userInfo})
    .then(response => response.data)

    return {
        type : actionTypesUser.USER_SIGNUP,
        payload: request
    }
}

 

다시 SignupComponent로 넘어와서 NextJS의 라우터를 사용해 회원가입 성공 시 로그인 화면으로 넘어가게끔 하자.

 

SignupComponent.tsx

import { useRouter } from 'next/router'

(...)

const Signup:NextPage<Props> = ({userChangeHandler,userState}) => {

(...)

    // router
    const router = useRouter()
    
(...)

    const submitHandler = (event : any) => {
        event.preventDefault();
        if(!userState.idDuple) {
            alert('아이디 중복여부를 체크해주세요.');
        }else {
            if(!userState.emailDuple) {
                alert('이메일 중복여부를 확인해주세요.');
            }else {
                if(!userState.emailAuth) {
                    alert('이메일 인증을 확인해주세요.');
                }else {
                    if(userState.userInfo.pw.length < 4) {
                        alert('비밀번호를 4자이상 입력해주세요.');
                    } else {
                        if(userState.userInfo.pw !== pwdCertText) {
                            alert('비밀번호와 비밀번호 확인 문자가 다릅니다.');
                        }
                        else {
                            // add address detail
                            dispatch({type : actionTypesUser.USER_INFO, data: ['address',userState.userInfo.address + addressDetail]})
                            // signup dispatch
                            dispatch(userSignup(userState.userInfo)).then((req: any) => {
                                if(req.payload.result) {
                                    alert('회원가입 성공입니다.')
                                    router.push('/auth/login');
                                }
                                else {
                                    alert('회원가입 오류입니다.');
                                }
                            })
                        }
                    }
                }
            }
        }
    }

 

이제 프론트에서 할 일은 끝났다. 백엔드에서 값이 잘 들어왔는지 확인하고 올바른 결과값을 반환해주자.

 

먼저 필요한 것들을 설치하고 dto를 설정해준다.

$ npm i class-validator class-transformer

 

create-user.dto.ts

import {IsString, IsNumber} from 'class-validator'

export class CreateUserDto {
    @IsString()
    id : string;

    @IsString()
    pw : string;

    @IsString()
    email : string;

    @IsString()
    address : string;
}

 

main.ts 파일에서 ValidationPipe를 사용한다.

maints

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as cookieParser from 'cookie-parser';
import { ValidationPipe } from '@nestjs/common';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.use(cookieParser());

  app.useGlobalPipes(
    new ValidationPipe({
      whitelist : true, 
      forbidNonWhitelisted : true,
      transform : true
    })
  )

  await app.listen(3001);
}
bootstrap();

 

 

 

컨트롤러에 signup 함수를 지정해준다.

 

user.controller.ts

import { Controller, Get, Post, Body, Patch, Param, Delete, Res, Req } from '@nestjs/common';
import { UserService } from './user.service';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';

@Controller('user')
export class UserController {
  constructor(private readonly userService: UserService) {}

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.userService.findOne(id);
  }

  @Post('signup')
  async signUp(@Res({ passthrough: true}) res : any, @Req() req : any) {
    return this.userService.signUp(req.body.userInfo);
  }

}

 

서비스 부분에서 비밀번호를 암호화하고 DB에 저장하는 함수를 선언한다.

 

user.service.ts

import { Injectable } from '@nestjs/common';
//mongoose
import { Model } from 'mongoose';
import { InjectModel } from '@nestjs/mongoose';
import { User, UserDocument } from './schemas/user.schema';
//dto
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
//bcrypt
import * as bcrypt from 'bcrypt'

@Injectable()
export class UserService {
  constructor(@InjectModel(User.name) private userModel: Model<UserDocument>) {}

  async findOne(id: string) {
    const userOne = await this.userModel.findOne({id});
    if(userOne)
      return {result : false, user : userOne};
    else
      return {result : true};
  }

  async signUp(userInfo : CreateUserDto) {
    try{
      const authPW = await bcrypt.hash(userInfo.pw,parseInt(process.env.saltOrRounds));
      const createUser = await this.userModel.create({
        id : userInfo.id,
        pw : authPW,
        email : userInfo.email,
        address : userInfo.address
      })
      return {result : true};
    }catch(e) {
      return {result : false};
    }
  }
}

 

 

이제 실행을 해본다!

 

 

회원가입 버튼 클릭 후 :

 

alert 창의 확인버튼 누른 후 : 

 

정상적으로 로그인 페이지로 넘어오는것을 확인할 수 있다.

참고로 robo 3t라는 프로그램으로 들어온 mongoDB 데이터를 확인할 수 있다.

 

728x90
반응형

+ Recent posts