Skip to content

Commit

Permalink
더미데이터로 로그인 기능 SSR로 구현 (#128)
Browse files Browse the repository at this point in the history
* feat: 저장 로직 초기세팅

* feat: DummyProperties 추가

* 비밀번호 및 오류 출력 로직 추가

* refactor: 코드 정렬

* feat: 이메일 목록에서 찾는 로직 추가, 에러 메시지 이후에도 목록 유지

* teat: findAllByEmailIn로직 테스트 코드 추가

* feat: css추가
  • Loading branch information
GitJIHO authored Oct 31, 2024
1 parent 53151a3 commit b5b1086
Show file tree
Hide file tree
Showing 7 changed files with 205 additions and 2 deletions.
3 changes: 2 additions & 1 deletion src/main/java/com/example/sinitto/SinittoApplication.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.example.sinitto;

import com.example.sinitto.common.properties.DummyProperties;
import com.example.sinitto.common.properties.KakaoProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
Expand All @@ -9,7 +10,7 @@

@SpringBootApplication
@EnableJpaAuditing
@EnableConfigurationProperties(KakaoProperties.class)
@EnableConfigurationProperties({KakaoProperties.class, DummyProperties.class})
@EnableScheduling
public class SinittoApplication {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.example.sinitto.common.properties;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "dummy")
public record DummyProperties(
String devRedirectUri,
String redirectUri,
String password
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.example.sinitto.member.controller;

import com.example.sinitto.auth.service.TokenService;
import com.example.sinitto.common.properties.DummyProperties;
import com.example.sinitto.member.entity.Member;
import com.example.sinitto.member.repository.MemberRepository;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.Arrays;
import java.util.List;

@Controller
@RequestMapping("/dummy")
public class MemberAdminController {

private final MemberRepository memberRepository;
private final TokenService tokenService;
private final DummyProperties dummyProperties;

private final List<String> dummyEmails = Arrays.asList(
"[email protected]", "[email protected]", "[email protected]", "[email protected]", "[email protected]",
"[email protected]", "[email protected]", "[email protected]", "[email protected]", "[email protected]"
);

public MemberAdminController(MemberRepository memberRepository, TokenService tokenService, DummyProperties dummyProperties) {
this.memberRepository = memberRepository;
this.tokenService = tokenService;
this.dummyProperties = dummyProperties;
}

@GetMapping
public String showDummyLoginPage(Model model) {
List<Member> dummyMembers = memberRepository.findAllByEmailIn(dummyEmails);
model.addAttribute("members", dummyMembers);
return "dummy/login";
}

@PostMapping
public String login(
@RequestParam("email") String email,
@RequestParam("password") String password,
@RequestParam("env") String env,
Model model
) {
List<Member> dummyMembers = memberRepository.findAllByEmailIn(dummyEmails);
model.addAttribute("members", dummyMembers);

if (!password.equals(dummyProperties.password())) {
model.addAttribute("errorMessage", "비밀번호가 일치하지 않습니다.");
return "dummy/login";
}

Member member = memberRepository.findByEmail(email).orElse(null);
if (member == null) {
model.addAttribute("errorMessage", "해당 이메일을 가진 멤버를 찾을 수 없습니다. 데이터베이스에서 삭제되었는지 확인해주세요.");
return "dummy/login";
}
String accessToken = tokenService.generateAccessToken(email);
String refreshToken = tokenService.generateRefreshToken(email);
boolean isSinitto = member.isSinitto();

String frontendRedirectUrl = env.equals("dev") ? dummyProperties.devRedirectUri() : dummyProperties.redirectUri();
return "redirect:" + frontendRedirectUrl + "?accessToken=" + accessToken + "&refreshToken=" + refreshToken + "&isSinitto=" + isSinitto;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,7 @@ public interface MemberRepository extends JpaRepository<Member, Long> {
boolean existsByEmail(String email);

List<Member> findByIsSinitto(boolean isSinitto);

List<Member> findAllByEmailIn(List<String> emails);

}
67 changes: 67 additions & 0 deletions src/main/resources/static/css/dummy.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 20px;
}

h2 {
color: #333;
text-align: center;
}

p {
text-align: center;
font-size: 14px;
}

form {
background-color: #fff;
padding: 20px;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
max-width: 400px;
margin: 20px auto;
}

label {
font-weight: bold;
display: block;
margin-bottom: 5px;
}

select,
input[type="password"] {
width: 100%;
padding: 10px;
margin-bottom: 15px;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 14px;
}

.button-container {
display: flex;
justify-content: space-between;
}

button {
background-color: #28a745;
color: white;
border: none;
padding: 10px;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
width: 48%; /* 버튼 너비 조정 */
}

button:hover {
background-color: #218838;
}

.error-message {
color: red;
text-align: center;
margin-top: 10px;
}
33 changes: 33 additions & 0 deletions src/main/resources/templates/dummy/login.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>더미데이터 유저 로그인</title>
<link href="/css/dummy.css" rel="stylesheet">
</head>
<body>
<h2>더미데이터 유저 로그인</h2>
<p style="color: black; font-weight: bold;">
해당 페이지는 개발자용 페이지입니다. 더미데이터 유저만 로그인이 가능합니다.
</p>
<p th:if="${errorMessage}" th:text="${errorMessage}" style="color: red;"></p>

<form th:action="@{/dummy}" method="post">
<label for="email">이메일:</label>
<select id="email" name="email" required>
<option value="" disabled selected>이메일을 선택하세요</option>
<option th:each="member, iterStat : ${members}" th:value="${member.email}"
th:text="${member.email + ' (' + (member.isSinitto ? '시니또' : '보호자') + ' ' + (iterStat.index + 1) + ')'}">
</option>
</select>
<br><br>

<label for="password">비밀번호:</label>
<input type="password" id="password" name="password" required/><br><br>

<div class="button-container">
<button type="submit" name="env" value="dev">개발 환경으로 로그인</button>
<button type="submit" name="env" value="prod">배포 서버로 로그인</button>
</div>
</form>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.assertj.core.api.Assertions.assertThat;

@DataJpaTest
public class MemberRepositoryTest {
Expand Down Expand Up @@ -67,4 +69,20 @@ void notExistsByEmailTest() {
assertThat(exists).isFalse();
}

@Test
@DisplayName("이메일 목록을 이용한 멤버 조회 테스트")
void findAllByEmailInTest() {
Member member1 = new Member("test1", "01011112222", "[email protected]", true);
Member member2 = new Member("test2", "01022223333", "[email protected]", false);
Member member3 = new Member("test3", "01033334444", "[email protected]", true);
memberRepository.saveAll(Arrays.asList(member1, member2, member3));

List<String> emails = Arrays.asList("[email protected]", "[email protected]");

List<Member> members = memberRepository.findAllByEmailIn(emails);

assertThat(members).hasSize(2);
assertThat(members).extracting("email").containsExactlyInAnyOrder("[email protected]", "[email protected]");
}

}

0 comments on commit b5b1086

Please sign in to comment.