728x90
반응형

회원가입 완료 후 회원가입된 아이디 비밀번호로 로그인이 성공하면 대쉬보드 페이지로 넘어가는 서비스를 구현해보자.

 

먼저 SignupComponent와 LoginComponent에 useEffect로 해당 컴포넌트에 처음 들어갈 때 userState를 초기화하는 구문을 넣어준다. 이 구문을 넣지 않으면 회원가입에서 진행했던 내용들이 그대로 로그인 화면에도 쓰이게 된다.

 

    useEffect(()=> {
        dispatch({type: actionTypesUser.USER_INIT})
    },[])

 

[cate].tsx에서 SignupComponent에 전달했던 값과 똑같은 값을 LoginComponent에 넘겨준다.

 

[cate].tsx

            <LoginComponent
                userChangeHandler={userChangeHandler} // 로그인에 props로 Handler함수를 보낸다.
                userState={userState} /> : ""}

 

로그인 화면을 다음과같이 구성해준다.

 

LoginComponent.tsx

import type { NextPage } from 'next'
import { actionTypesUser, UserState } from "../../store/interfaces/";
import { useEffect } from 'react'
import { useDispatch } from 'react-redux';
import Link from 'next/link'

interface Props {
    userChangeHandler : (event : any) => void;
    userState : UserState;
}

const Login:NextPage<Props> = ({userChangeHandler,userState}) => {
    const dispatch = useDispatch();

    useEffect(()=> {
        dispatch({type: actionTypesUser.USER_INIT});
    },[])

    const LoginHandler = (event : any) => {
        event.preventDefault();
    }
    
    return (
        <div className='login'>
            <form onSubmit={LoginHandler}>
                <div>
                    <input 
                        name="id"
                        type="text"
                        placeholder="Enter ID"
                        onChange={userChangeHandler} />
                </div>
                <div>
                    <input 
                        name="pw"
                        type="password"
                        placeholder="Enter PW"
                        onChange={userChangeHandler} />
                </div>
                <div>
                    <button
                        type="submit">
                    Login
                    </button>
                </div>
                <Link href={`/auth/signup`}>
                    <a> 회원가입 화면으로 가기 </a>
                </Link>
            </form>
        </div>
        )
}


export default Login

아이디 입력창과 비밀번호 입력창, 로그인 버튼과 Link를 사용해 화면을 구성했다. 회원가입에서 이미 다뤘던 내용들이라 자세한 설명은 하지 않겠다. 

 


next/link에 관한 자세한 내용은 다음 링크에서 확인할 수 있다.

https://nextjs.org/docs/api-reference/next/link

 

next/link | Next.js

Enable client-side transitions between routes with the built-in Link component.

nextjs.org


화면을 확인해보면 

 

 

이제 로그인 버튼을 눌렀을 경우 DB를 조회하고 해당 아이디 비밀번호가 올바르면 로그인 성공 메세지가 뜨게 할 것이다.

 

먼저 로그인에 필요한 액트, 타입, 리듀서, 액션을 만들어주자.

 

userAct.interfaces.ts

(...)

USER_LOGIN = "USER_LOGIN", // 로그인

(...)
    
export type ActionsUser = UserInit | UserState | UserInfo | UserIdDuplicate
                         | UserEmailDuplicate | UserEmailSend | UserEmailCert
                         | UserSignup | UserLogin
                         
(...)
                         
export interface UserLogin {
    type : actionTypesUser.USER_LOGIN;
    payload : any;
}

 

user_reducer.ts

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

 

user_action.ts

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

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

 

 

그다음 LoginHandler 함수를 다음과 같이 조건식을 세워서 만든다.

 

LoginComponent.tsx

    const LoginHandler = (event : any) => {
        event.preventdefault();
        dispatch(userLogin(userState.userInfo)).then((req : any) => {
            if(req.payload.result === "success") { // 로그인 성공 시 
                alert('로그인 성공입니다.');
            }
            else if(req.payload.result === "IdFailed") { // 아이디가 없을 경우
                alert('존재하지 않는 아이디입니다.');
            }else if(req.payload.result === "PwFailed"){ // 비밀번호가 틀릴경우
                alert('비밀번호가 틀렸습니다.');
            }else { // 그 외의 경우
                alert('로그인 실패입니다.');
            }
        })
    }

 

이제 프론트에서 할 일은 끝났다. 백엔드로 넘어가보자. 먼저 컨트롤러 부분에 login Post데코레이터를 만들어준다.

 

user.controller.ts

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

 

user.service.ts

  async logIn(userInfo : CreateUserDto, res : any) {
    try {
      const userOne = await this.userModel.findOne({id : userInfo.id});
      if(userOne) { // ID가 존재할 경우
        const result = await bcrypt.compare(userInfo.pw,userOne.pw); 
        if(result) { // 비밀번호가 일치할 경우
          res.cookie('isLogined',userInfo.id, {path: '/', expires: new Date(Date.now()+86400000)});
          return { result : "success"};
        }
        else { // 비밀번호가 틀릴 경우
          return { result : "PwFailed"};
        }
      }else { // ID가 없을 경우
        return { result : 'IdFailed'};
      }
    }catch(e) {
      return false;
    }
  }

 

이제 화면에서 로그인이 성공했을 때 쿠키가 제대로 생기는지 확인해보자.

 

- 존재하지 않는 ID일 경우

 

- 비밀번호가 틀릴 경우

 

- 로그인이 성공할 경우

 

쿠키까지 확인 : 

 

로그인 성공 시 쿠키가 잘 생성되는것을 확인했다.

 

마지막으로 로그인이 완료되면 넘어갈 페이지인 대시보드 페이지를 만들어보자.

 

/pages/dashboard.tsx

import type { NextPage } from 'next'
import Link from 'next/link'


const Dashboard:NextPage = () => {
    return (
        <div className='dashboard'>
            Dashboard
        </div>
        )
}


export default Dashboard

 

LoginComponent.tsx

    const LoginHandler = (event : any) => {
        event.preventDefault();
        dispatch(userLogin(userState.userInfo)).then((req : any) => {
            if(req.payload.result === "success") { // 로그인 성공 시 
                alert('로그인 성공입니다.');
                router.push(`/dashboard`)
            }
            else if(req.payload.result === "IdFailed") { // 아이디가 없을 경우
                alert('존재하지 않는 아이디입니다.');
            }else if(req.payload.result === "PwFailed"){ // 비밀번호가 틀릴경우
                alert('비밀번호가 틀렸습니다.');
            }else { // 그 외의 경우
                alert('로그인 실패입니다.');
            }
        })
    }

 

router.push를 이용해 성공시 대쉬보드 페이지로 넘어가게끔 했다.

728x90
반응형

+ Recent posts