보라코딩

jwt를 이용한 회원가입 (리액트 + JPA) 본문

코딩/Spring

jwt를 이용한 회원가입 (리액트 + JPA)

new 보라 2023. 8. 13. 17:58

솔직히 어렵다........

 

 

 

 

UserEntity
package com.boralog.blog.domain;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

import com.boralog.blog.dto.SignUpDto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity(name = "User")
@Table(name = "User")
public class UserEntity {

@Id
private String userEmail;
private String userPassword;
private String userNickname;
private String userPhoneNumber;
private String userAddress;
private String userProfile;

public UserEntity(SignUpDto dto) {
this.userEmail = dto.getUserEmail();
this.userPassword = dto.getUserPassword();
this.userNickname = dto.getUserNickname();
this.userPhoneNumber = dto.getUserPhoneNumber();
this.userAddress = dto.getUserAddress() + " " + dto.getUserAddressDetail();

}
}

 

 

 

UserRepository
package com.boralog.blog.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.boralog.blog.domain.UserEntity;

@Repository
public interface UserRepository extends JpaRepository<UserEntity, String> {

public boolean existsByUserEmailAndUserPassword(String userEmail, String userPassword);

}

 

 

 

 

AuthController
package com.boralog.blog.web;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.boralog.blog.dto.ResponseDto;
import com.boralog.blog.dto.SignInDto;
import com.boralog.blog.dto.SignInResponseDto;
import com.boralog.blog.dto.SignUpDto;
import com.boralog.blog.service.AuthService;

//@CrossOrigin(originPatterns = "http://localhost:3000")
@RestController
@RequestMapping("/api/auth")
public class AuthController {

@Autowired
AuthService authService;

@PostMapping("/signUp")
public ResponseDto<?> signUp(@RequestBody SignUpDto requestBody) {

ResponseDto<?> result = authService.signUp(requestBody);

return result;
}

@PostMapping("/signIn")
public ResponseDto<SignInResponseDto> signIn(@RequestBody SignInDto requestBody) {

System.out.println(requestBody);
ResponseDto<SignInResponseDto> result = authService.signIn(requestBody);
return result;
}

}

 

 

 

 

AuthService

 

package com.boralog.blog.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.boralog.blog.domain.UserEntity;
import com.boralog.blog.dto.ResponseDto;
import com.boralog.blog.dto.SignInDto;
import com.boralog.blog.dto.SignInResponseDto;
import com.boralog.blog.dto.SignUpDto;
import com.boralog.blog.repository.UserRepository;
import com.boralog.blog.security.TokenProvider;

@Service
public class AuthService {

@Autowired
UserRepository userRepository;

@Autowired
TokenProvider tokenProvider;

public ResponseDto<?> signUp(SignUpDto dto) {

String userEmail = dto.getUserEmail();
String userPassword = dto.getUserPassword();
String userPasswordCheck = dto.getUserPasswordCheck();

// email 중복확인
try {
if (userRepository.existsById(userEmail)) {
return ResponseDto.setFailed("Existed Email!");
}
} catch (Exception e) {
return ResponseDto.setFailed("DB error!");
}

// 비밀번호 다르면 failed response 반환

if (!userPassword.equals(userPasswordCheck)) {
return ResponseDto.setFailed("Password does not matched!");

}

// UserEntity 생성
System.out.println("UserEntity 생성!");
UserEntity userEntity = new UserEntity(dto);

// UserRepository 이용해서 DB에 Entity 저장
try {
userRepository.save(userEntity);
} catch (Exception e) {
return ResponseDto.setFailed("DB Error!");
}

// 성공시
System.out.println("성공시 return~");
return ResponseDto.setSuccess("Sign Up Success!", null);
}

public ResponseDto<SignInResponseDto> signIn(SignInDto dto) {
String userEmail = dto.getUserEmail();
String userPassword = dto.getUserPassword();

try {
boolean existed = userRepository.existsByUserEmailAndUserPassword(userEmail, userPassword);
if (!existed)
return ResponseDto.setFailed("Sign In Information does not match!");
} catch (Exception error) {
return ResponseDto.setFailed("DB error");
}

UserEntity userEntity = null;
try {
userEntity = userRepository.findById(userEmail).get();
} catch (Exception error) {
return ResponseDto.setFailed("DB error");
}

userEntity.setUserPassword("");

String token = tokenProvider.create(userEmail);
int exprTime = 3600000;

SignInResponseDto signInResponseDto = new SignInResponseDto(token, exprTime, userEntity);
return ResponseDto.setSuccess("Sign in Success", signInResponseDto);

}
}

 

 

 

 

 

 

dto

 

 

 

ResponseDto
package com.boralog.blog.dto;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor(staticName = "set")
public class ResponseDto<D> {

private boolean result;
private String message;
private D data;

public static <D> ResponseDto<D> setSuccess(String message, D date) {
return ResponseDto.set(true, message, date);
}

public static <D> ResponseDto<D> setFailed(String message) {
return ResponseDto.set(false, message, null);
}
}

 

 

 

SignUpDto
package com.boralog.blog.dto;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class SignUpDto {

private String userEmail;
private String userPassword;
private String userPasswordCheck;

private String userNickname;
private String userPhoneNumber;
private String userAddress;
private String userAddressDetail;

}

 

 

 

SignInDto
package com.boralog.blog.dto;

import javax.validation.constraints.NotBlank;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class SignInDto {

@NotBlank
private String userEmail;
@NotBlank
private String userPassword;
// private UserEntity user;
}

 

 

 

SignInResponseDto
package com.boralog.blog.dto;

import com.boralog.blog.domain.UserEntity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class SignInResponseDto {

private String token;
private int exprTime;
private UserEntity user;

}

 

 

 



 

 

App.js

import logo from "./logo.svg";
import "./App.css";
import React, { useEffect, useState } from "react";
import axios from "axios";
import SignUp from "./view/SignUp";
import SignIn from "./SignIn";

function App() {
  return (
    <div>
      <SignUp />
      <SignIn />
    </div>
  );
}

export default App;

 

 

 

SignUp

//rfc
import React, { useState } from "react";
import axios from "axios";
import Box from "@mui/material/Box";
import TextField from "@mui/material/TextField";
import Card from "@mui/material/Card";
import CardActions from "@mui/material/CardActions";
import CardContent from "@mui/material/CardContent";
import Button from "@mui/material/Button";

export default function SignUp() {
  const [userEmail, setUserEmail] = useState("");
  const [userPassword, setUserPassword] = useState("");
  const [userPasswordCheck, setUserPasswordCheck] = useState("");
  const [userNickname, setNickname] = useState("");
  const [userPhoneNumber, setPhoneNumber] = useState("");
  const [userAddress, setAddress] = useState("");
  const [userAddressDetail, setAddressDetail] = useState("");

  const [requestResult, setRequestResult] = useState("");

  const SignUpHandler = () => {
    const data = {
      userEmail,
      userPassword,
      userPasswordCheck,
      userNickname,
      userPhoneNumber,
      userAddress,
      userAddressDetail,
    };

    axios
      .post("http://localhost:8080/api/auth/signUp", data)
      .then((response) => {
        setRequestResult("Success!!");
      })
      .catch((error) => {
        setRequestResult("fail....");
      });
  };

  return (
    <Card sx={{ minWidth: 275, maxWidth: "40vw" }}>
      <CardContent>
        <Box>
          <TextField
            fullWidth
            label="이메일 주소"
            type="email"
            variant="standard"
            onChange={(e) => setUserEmail(e.target.value)}
          />
          <TextField
            fullWidth
            label="비밀번호"
            type="password"
            variant="standard"
            onChange={(e) => setUserPassword(e.target.value)}
          />
          <TextField
            fullWidth
            label="비밀번호 확인"
            type="password"
            variant="standard"
            onChange={(e) => setUserPasswordCheck(e.target.value)}
          />
          <TextField
            fullWidth
            label="닉네임"
            variant="standard"
            onChange={(e) => setNickname(e.target.value)}
          />
          <TextField
            fullWidth
            label="휴대폰번호"
            variant="standard"
            onChange={(e) => setPhoneNumber(e.target.value)}
          />
          <TextField
            fullWidth
            label="주소"
            variant="standard"
            onChange={(e) => setAddress(e.target.value)}
          />
          <TextField
            fullWidth
            label="상세주소"
            variant="standard"
            onChange={(e) => setAddressDetail(e.target.value)}
          />

          <h3>{requestResult}</h3>
        </Box>
      </CardContent>
      <CardActions>
        <Button fullWidth onClick={SignUpHandler} variant="contained">
          회원가입
        </Button>
        <Button fullWidth onClick={SignUpHandler} variant="outlined">
          헤헤
        </Button>
      </CardActions>
    </Card>
  );
}

 

 

 

 

 

SignIn

//rfc
import { CardContent, TextField } from "@mui/material";
import axios from "axios";
import React, { useState } from "react";
import Box from "@mui/material/Box";
import Card from "@mui/material/Card";
import CardActions from "@mui/material/CardActions";
import Button from "@mui/material/Button";
import { useCookies } from "react-cookie";

export default function SignIn() {
  const [userEmail, setEmail] = useState("");
  const [userPassword, setPassword] = useState("");
  const [cookies, setCookies] = useCookies("");

  const signInHandler = () => {
    if (userEmail.length === 0 || userPassword.length === 0) {
      alert("이메일과 비밀번호 입력하세요~");
      return;
    }

    const data = {
      userEmail,
      userPassword,
    };

    axios
      .post("http://localhost:8080/api/auth/signIn", data)
      .then((response) => {
        const responseData = response.data;
        console.log(responseData);
        if (!responseData.result) {
          alert("로그인에 실패했습니다.");
          return;
        }
        const { token, exprTime, user } = responseData.data;
        const expires = new Date();
        expires.setMilliseconds(expires.getMilliseconds + exprTime);

        setCookies("token", token, { expires });
        alert(cookies.token);
      })
      .catch((error) => {
        alert("로그인에 실패했습니다.");
      });
  };

  return (
    <Card sx={{ minWidth: 275, maxWidth: "40vw" }}>
      <CardContent>
        <Box>
          <TextField
            fullWidth
            label="이메일"
            type="email"
            variant="standard"
            onChange={(e) => setEmail(e.target.value)}
          />
          <TextField
            fullWidth
            label="비밀번호"
            type="password"
            variant="standard"
            onChange={(e) => setPassword(e.target.value)}
          />
        </Box>
      </CardContent>
      <CardActions>
        <Button fullWidth onClick={signInHandler} variant="contained">
          로그인
        </Button>
      </CardActions>
    </Card>
  );
}