본문 바로가기

JAVA/- Spring

React와 Spring으로 로그인 화면 만들어보기

DB에는 

email과 passwd로 로그인을 허락하려고 생각했습니다.

 

react에서 email과 passwd를 보내면

spring에서 select * from member_table where email="dnjsalsgh123@gmail.com" and passwd="1234"; 이런 쿼리를 동작해서 값이 있다면 테이블을 json 객체로 넘겨주고 아니면 예외처리를 해보려고 합니다.

 

 

이런 화면에서 email과 passwd를 가져와야 합니다.

 

  const [inputId, setInputId] = useState("");
  const [inputPw, setInputPw] = useState("");
  
    const handleInputId = (e) => {
    setInputId(e.target.value);
  };

  const handleInputPw = (e) => {
    setInputPw(e.target.value);
  };
  
  <input
    type="email"
    className="form-control"
    placeholder="Enter email"
    name="input_id"
    value={inputId}
    onChange={handleInputId}
  />
  
  <input
    type="password"
    className="form-control"
    placeholder="Enter password"
    name="input_pw"
    value={inputPw}
    onChange={handleInputPw}
  />

이렇게 input에 value를 state로 관리하고 inputId, inputPw 라는 state에 email과 pw가 쌓여있습니다. 이제 이걸 spring으로 보내야 합니다.

 

const onClickLogin = () => {
    console.log("click login");
    console.log("ID : ", inputId);
    console.log("PW : ", inputPw);
    axios
      .post("http://localhost:8080/api/login", {
        email: inputId,
        passwd: inputPw,
      })
      .then((res) => {
        console.log(res);
        console.log("res.data.userId :: ", res.data.userId);
        console.log("res.data.msg :: ", res.data.msg);
        if (res.data.email === undefined) {
          // id 일치하지 않는 경우 userId = undefined, msg = '입력하신 id 가 일치하지 않습니다.'
          console.log("======================", res.data.msg);
          alert("입력하신 id 가 일치하지 않습니다.");
        } else if (res.data.email === null) {
          // id는 있지만, pw 는 다른 경우 userId = null , msg = undefined
          console.log(
            "======================",
            "입력하신 비밀번호 가 일치하지 않습니다."
          );
          alert("입력하신 비밀번호 가 일치하지 않습니다.");
        } else if (res.data.email === inputId) {
          // id, pw 모두 일치 userId = userId1, msg = undefined
          console.log("======================", "로그인 성공");
          sessionStorage.setItem("user_id", inputId); // sessionStorage에 id를 user_id라는 key 값으로 저장
          sessionStorage.setItem("name", res.data.name); // sessionStorage에 id를 user_id라는 key 값으로 저장
        }
        // 작업 완료 되면 페이지 이동(새로고침)
        document.location.href = "/";
      })
      .catch();
  };
  
  
  
  <button
    type="button"
    onClick={onClickLogin}
  >
    확인
  </button>

확인 버튼을 누르면 동작하는 onClickLogin입니다.

 

axios로 post요청을 보내는데 { email : "~~.gmail.com", passwd : "1234" } 이런식으로 data와 같이 spring에 도착하게 됩니다.

 

Contorller

@CrossOrigin(origins = "*")
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class MemberController {

    private final MemberService memberService;

    @PostMapping("/login")
    public MemberResponseDto login(@RequestBody final MemberRequestDto params) {
        MemberResponseDto entity = memberService.findBy(params);
        return entity;
    }

}

local에서 test를 하고 있기 때문에 react와 spring이 충돌 안나려면 CrossOrigin 설정을 해야합니다.

 

우리의 목표는 controller에 "/login"으로 매핑된것이 들어오면 db에서 찾은 후 json으로 보내야합니다.

 

Dto

@RequestBody로 http 요청에 있는 Body부분을 가져와서 email과 passwd를 사용할 수 있게됩니다.

 

 

Service

@Service
@RequiredArgsConstructor
public class MemberService {

    //final 붙여야지 생성자 만들어줌
    private final MemberRepository memberRepository;

    public MemberResponseDto findBy(final MemberRequestDto params){
        MemberResponseDto entity = memberRepository.findByEmailAndPasswd(params.getEmail(), params.getPasswd());
        return entity;
    }

}

Service 에서는 email과 passwd를 가져와서 JPA로 쿼리문을 만들어서 json형태로 반환할 준비를 하고 있습니다.

 

public interface MemberRepository extends JpaRepository<Member_table, Long>{

    MemberResponseDto findByEmailAndPasswd(final String email, final String passwd);

}

Jpa로 쿼리를 만드는 인터페이스 입니다.

jpa에서 where문을 어떻게 and를 하는가를 찾아봤더니 매서드 이름을 컬럼명and컬럼명을 하면 됩니다. (이 때 주의해야할 점이 컬럼의 첫 글자는 대문자로 시작합니다.)

 

이제 로그인을 성공 하면 

이런 형태로 data 부분에 db에서 가지고 온 내용이 있습니다. 

onClickLogin 마지막 부분쯤에 로그인이 성공하면 sessionStorageItem으로 닉네임(name)을 넣습니다. 그리고 document.location.href="/";로 메인페이지로 이동합니다.

 

 

메인 페이지

  const [isLogin, setIsLogin] = useState(false); //로그인 관리


  useEffect(() => {
    if (sessionStorage.getItem("name") === null) {
      // sessionStorage 에 name 라는 key 값으로 저장된 값이 없다면
      console.log("isLogin ?? :: ", isLogin);
    } else {
      // sessionStorage 에 name 라는 key 값으로 저장된 값이 있다면
      // 로그인 상태 변경
      setIsLogin(true);
      console.log("isLogin ?? :: ", isLogin);
    }
  });

로그인이 되어있다면 isLogin은 true가 되고 아니면 false가 됩니다.

{/* 로그인이 되어있다면 */}
    {isLogin ? (
        <Link to={`/MyPage`} className="nav-link text-white">
          {sessionStorage.getItem("name")}
        </Link>
    ) : (
        <Link to={`/Sign`} className="nav-link text-white">
          로그인
        </Link>
)}

3항연산자를 활용해서 로그인이 됐다면 페이지에 닉네임을 띄우고 아니라면 로그인 페이지를 띄웁니다.

 

참고

https://ddeck.tistory.com/35

https://devfunny.tistory.com/426

728x90