React Web Structure Test6

리액트 디자인 / 로그인 기능

Posted by ETHAN KIM on April 09, 2022 · 13 mins read
React PHP

주요 개념

  • Auth 페이지 내 입력 아이디 / 패스워드 validation 로직
  • php 서버 로그인 정보 확인 후 접속 token 생성
  • return 받은 token은 브라우저 session storage에 저장


실습 환경

  • nodejs react 패키지


구현 결과


./Auth.js

  • 이메일 형식 / 비밀번호 길이 체크 method 구현
  • 서버 로그인 fetch 요청
//------------------------------ MODULE -------------------------------------
import { useState } from "react";
import { Logo, Login } from "Components";
import styled from "styled-components";
import { login,  } from "lib";
import { useNavigate } from 'react-router-dom';

//------------------------------ CSS ----------------------------------------
const StyledAuth = styled.div`
    background-image : url("https://visme.co/blog/wp-content/uploads/2020/02/1-Animated-Presentation-Template.gif");
    height:100%;
    overflow:hidden;
`;
const StyledLogin = styled.div`
    background:white;
    height:650px;
    width:500px;
    margin:100px;
    float:right;
`;
const StyledTitle = styled.div`
    font-weight:bold;
    font-size : 40px;
    padding:20px 80px;
`;
const StyledEtc = styled.div`
    padding: 150px 80px 15px;
`;



//------------------------------ COMPONENT -----------------------------------
const Auth = () => {
    const navigate = useNavigate(); 

    const [account, setAccount] = useState({
        id: "",
        password: "",
    });

    const [ic, setIc] = useState(0);

    const [pc, setPc] = useState(0);
    
    const enterkey = () => {
        if(window.event.keyCode == 13){
            login_exec();
        }
    }

    const validation = (target) => {
        if(target.name == 'id'){
            if(!target.value){
                target.style.border = "solid 1px #4527A0";
                document.getElementById('id_msg').innerText = '';
                setIc(0);            
            }else if(!target.value.includes('@') || !target.value.includes('.')){ //id validation
                target.style.border = "solid 1px #FF4500";
                document.getElementById('id_msg').style.color = "#FF4500";
                document.getElementById('id_msg').innerText = 'invalid Email characters';
                setIc(0);
            }else{
                target.style.border = "solid 1px #228B22";
                document.getElementById('id_msg').style.color = "#228B22";
                document.getElementById('id_msg').innerText = 'Validation Success';
                setIc(1);
            }
        }
        if(target.name == 'password'){ //password validation
            if(!target.value){
                target.style.border = "solid 1px #4527A0";
                document.getElementById('pw_msg').innerText = '';
                setIc(0);            
            }else if(target.value.length < 8){
                target.style.border = "solid 1px #FF4500";
                document.getElementById('pw_msg').style.color = "#FF4500";
                document.getElementById('pw_msg').innerText = 'invalid Password characters';
                setPc(0);
            }else{
                target.style.border = "solid 1px #228B22";
                document.getElementById('pw_msg').style.color = "#228B22";
                document.getElementById('pw_msg').innerText = 'Validation Success';
                setPc(1);
            }            
        }
    }

    const onChangeInput = (e) => {
        setAccount({
            ...account,
            [e.target.name]: e.target.value
        });
        validation(e.target);
    };

    const login_exec = () => {
        let id_target = document.getElementsByName('id');
        let pw_target = document.getElementsByName('password');
        validation(id_target[0]);
        validation(pw_target[0]);
        if(id_target[0].value == ''){
            id_target[0].style.border = "solid 1px #FF4500";
            document.getElementById('id_msg').style.color = "#FF4500";
            document.getElementById('id_msg').innerText = 'Please enter your ID';
        }
        if(pw_target[0].value == ''){
            pw_target[0].style.border = "solid 1px #FF4500";
            document.getElementById('pw_msg').style.color = "#FF4500";
            document.getElementById('pw_msg').innerText = 'Please enter your PASSWORD';
        }        
        if(ic && pc){
            login(account)
            .then(result => {
                sessionStorage.setItem('token', result);
                return result ? navigate('/') : alert('login fail');               
            }) 
        }
    }    

    return (
        <>
        <StyledAuth>            
            <StyledLogin>
            <StyledTitle>
                <Logo src = {"https://logolab.app/assets/logo.png"}></Logo>                                      
                <div>Login</div>                
            </StyledTitle>
            <Login onChangeInput={onChangeInput} login_exec={login_exec} validation={validation} enterkey={enterkey}/>
            <StyledEtc>
                @2022 MW reserved All rights reserved
            </StyledEtc>
            </StyledLogin>
        </StyledAuth>
        </>
    )     
}

export default Auth;


./component/Structure/Login/Login.js

  • 로그인 form
//------------------------------ MODULE -------------------------------------
import styled from "styled-components";

//------------------------------ CSS ----------------------------------------
const StyledInput = styled.div`
    padding:20px 80px;
    font-weight:bold;
    font-size : 13px;
    &>input {
        border-radius:100px;
        border:solid 1px #4527A0;
        width: 95%;
        margin-top :5px;
        padding: 8px 10px;
        &:focus{
            outline:none;
        }
    }    
    &>a {
        height:20px;  
        border-radius: 100px;      
        grid-column: span 2;
    }     
    .chk_box{
        float:left;
    }   
    .chk_password{
        cursor:pointer; 
        float:right;
    }
    .chk_account{
        cursor:pointer; 
        color:#4527A0;        
    }
    #id_msg{
        font-size : 10px;
        margin:10px;
    }
    #pw_msg{
        font-size : 10px;
        margin:10px
    }
    #id_label{
        margin-top:10px;
    }
    #pw_label{
        margin-top:10px
    }    
`;

const StyledButton = styled.button`
    width:100%;
    height:35px;
    background:#4527A0;
    color:white;
    margin:30px 0px;
    border-radius: 100px;
    border:none;
    cursor:pointer;
`;

//------------------------------ COMPONENT ----------------------------------
const Login = (props) => {
    return(
        <>
            <StyledInput>
                <div id="id_label">Email * </div>
                <input name="id" onChange ={props.onChangeInput} onKeyUp={props.enterkey} placeholder={"mail@website.com"} ></input>
                <span id="id_msg"></span>
                <div id="pw_label">Password * </div>
                <input name="password" type={"password"} onChange={props.onChangeInput} onKeyUp={props.enterkey} placeholder={"Min, 8 chrarcters"} ></input>
                <span id="pw_msg"></span>
                <br/>
                <br/>
                <div>
                    <span className="chk_box"><input type={"checkbox"}/></span><span> Remember me</span>
                    <span className="chk_password">Forget Password ?</span>
                </div>
                <StyledButton onClick = {props.login_exec}>Login</StyledButton>
                <span>Not Registered yet? </span><span className="chk_account"> Create Account </span>
            </StyledInput>
        </>
    )
}

export default Login;



서버 – ./fetch/login_test.php

  • 서버쪽 로그인 체크 및 토큰생성
  • 별도 jwt 토큰 생성용 클래스 사용
<?php 
    /*###############################################################
        리액트 서버 로그인 테스트
    */###############################################################

    //setting
    $data = json_decode(file_get_contents('php://input'));
    $test = json_decode(file_get_contents("./login_info.json"), true);
    include_once("./jwt.php");
    header("Access-Control-Allow-Origin: *");
    header("Access-Control-Allow-Headers: *");    
    
    $chk = $data->id == $test['id'] && $data->password == $test['pw'];

    if($chk){
        $jwt = new JWT();
        $token = $jwt->hashing(array(
            'exp' => time() + (360 * 30),
            'iat' => time(),
            'id' => base64_encode($test['id'])
        ));        
    }
    
    echo json_encode($chk ? $token : null);
?>