Skip to content

Commit

Permalink
feat: 설문조사 페이지 생성
Browse files Browse the repository at this point in the history
Spring Security 사용하여 사용자 인증 로그인 후 설문조사 가능
  • Loading branch information
inpink committed Mar 29, 2024
1 parent 64ec3c4 commit 94d0efe
Show file tree
Hide file tree
Showing 13 changed files with 363 additions and 2 deletions.
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.jsoup:jsoup:1.16.1'
implementation 'org.json:json:20190722'
implementation 'org.springframework.boot:spring-boot-starter-data-elasticsearch'
Expand Down
2 changes: 2 additions & 0 deletions docs/deploy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
배포 잘 설명되어 있는 게시글
https://velog.io/@chae_ag/series%EB%B0%B0%ED%8F%ACSpring-Boot-GitHub-Actions-AWS-CodeDeploy%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-CICD-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0
20 changes: 20 additions & 0 deletions src/main/java/knusearch/clear/survey/Participant.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package knusearch.clear.survey;

import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;

@Entity
@Getter
@Setter
public class Participant {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "participant_id")
private Long id;

@Column(unique = true)
private String username;

private String password;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package knusearch.clear.survey;

import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class ParticipantDetailsService implements UserDetailsService {

private final ParticipantRepository participantRepository;
private final BCryptPasswordEncoder encoder;

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Participant participant = participantRepository.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("User not found"));
System.out.println(participant.getUsername());

return User.withUsername(participant.getUsername())
.password(encoder.encode(participant.getPassword()))
.roles("USER")
.build();
}
}
11 changes: 11 additions & 0 deletions src/main/java/knusearch/clear/survey/ParticipantRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package knusearch.clear.survey;

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

import java.util.Optional;

@Repository
public interface ParticipantRepository extends JpaRepository<Participant, Long> {
Optional<Participant> findByUsername(String username);
}
61 changes: 61 additions & 0 deletions src/main/java/knusearch/clear/survey/SecurityConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package knusearch.clear.survey;

import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

@EnableWebSecurity
@EnableMethodSecurity
@Configuration
@RequiredArgsConstructor
public class SecurityConfig {

private final ParticipantDetailsService participantDetailsService;

@Bean
public static BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}

@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring()
.requestMatchers(PathRequest.toStaticResources().atCommonLocations());
}

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

http
.authorizeHttpRequests(requests -> requests
.requestMatchers(
new AntPathRequestMatcher("/"),
new AntPathRequestMatcher("/home"),
new AntPathRequestMatcher("/search"),
new AntPathRequestMatcher("/searchResult"),
new AntPathRequestMatcher("/survey/login"))
.permitAll()
.anyRequest().authenticated()
)
.formLogin(form -> form
.loginPage("/survey/login")
.defaultSuccessUrl("/survey/queryNumber=1", true)
.permitAll()
)
.userDetailsService(participantDetailsService)
.logout(logout -> logout
.permitAll());

return http.build();
}

}
42 changes: 42 additions & 0 deletions src/main/java/knusearch/clear/survey/SurveyController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package knusearch.clear.survey;

import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
@Slf4j
public class SurveyController {
@GetMapping("/survey/login")
public String loginForm(Model model, HttpServletRequest request) {
CsrfToken csrfToken = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
if (csrfToken != null) {
model.addAttribute("_csrf", csrfToken);
}
return "survey/surveyLogin";
}

@PostMapping("/survey/login")
public String loginSubmit(@RequestParam("username") String username,
@RequestParam("password") String password) {
log.info("Username: " + username);
log.info("Password: " + password);



return "redirect:/survey/queryNumber=1";
}

@GetMapping("/survey/queryNumber={number}")
public String handleSurveyQuery(@PathVariable("number") int number) {

return "hello";
}

}
20 changes: 20 additions & 0 deletions src/main/java/knusearch/clear/survey/SurveyQuery.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package knusearch.clear.survey;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Getter;
import lombok.Setter;

@Entity
@Getter
@Setter
public class SurveyQuery {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String query;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package knusearch.clear.survey;

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

@Repository
public interface SurveyQueryRepository extends JpaRepository<SurveyQuery, Long> {
}
33 changes: 33 additions & 0 deletions src/main/java/knusearch/clear/survey/SurveyQueryService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package knusearch.clear.survey;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;

@Service
public class SurveyQueryService {

@Autowired
private SurveyQueryRepository repository;

@Transactional
public void loadQueriesFromFile(String filePath) {
try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
List<SurveyQuery> queries = new ArrayList<>();
String line;
while ((line = reader.readLine()) != null) {
SurveyQuery query = new SurveyQuery();
query.setQuery(line);
queries.add(query);
}
repository.saveAll(queries);
} catch (Exception e) {
e.printStackTrace();
}
}
}
100 changes: 100 additions & 0 deletions src/main/java/knusearch/clear/survey/surveyQueries.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
캐나다 교환학생
미국 교육
미국 온라인 교육
성격 유형 검사
성격 유형 검사 어디
심리 상담
심리 상담 비용
재학생 심리 상담
재학생 심리 상담 비용 문의
교환학생 휴학
휴학 문의
휴학 진행 문의
휴학 진행 문의 어디
학생 현재 미국 교환학생 진행 학생 학기 도중 휴학 진행 문의 어디
조기 졸업 학기
조기 졸업 학기 학년
조기 졸업
조기 졸업 학칙
조기 졸업 신청
조기 졸업 조건
조기 졸업 사례
학생 현재 학년 학점 조기 졸업 조건
학생 현재 학년 학점 학습 상담
사회복지학과 전공기초 강의명 리스트
전공 기초 전공 선택 차이점
사회복지학과 2급 자격증 필수과목
사회 복지 학과 자격증 필수 과목
융합 인재 장학금
융합 인재 장학금 발표
융합 인재 장학금 발표 언제
재학생 융합 인재 장학금 발표 언제
소프트웨어 전공 재학생 융합 인재 장학금 발표 언제 어디 얼마 지원
소프트웨어 전공 재학생입니다. 융합 인재 장학금 발표 언제, 어디에 나와요? 얼마 지원되는지 알려주세요. 또 문의 어디에 하면 되나요
현재 소프트웨어 전공 4학년 학생인데요, 재학생 대상으로 융합 인재 장학금은 발표가 언제 나죠? 어디서 나오는지 알려주세요 그리고 얼마 지원되죠? 이외의 문의 어디로 하면 되나요?
장학금 지원 성적
한국 장학재단 장학금 지원 조건
한국 장학재단 장학금 지원 성적 조건
한국 장학재단 장학금 지원 성적 조건 학점 이상
장학재단 장학금 지원 성적 조건 학점 이상
장학재단 장학금 지원 성적 조건 학점 이상 학년 학생
일본 학생 소프트웨어 전공 데이터 사이언스 전공 취업
일본 학생 소프트웨어 전공 데이터 사이언스 전공 전공 취직 일본 취업
1학기 수강신청 앱으로 하는 법
이미 수강한 과목 과목명 바뀌었을 때 학점 인정 가능한가요
장바구니 제도
교과목 장바구니 제도
안녕하세요 교과목 장바구니 제도에 대해 질문이 있습니다. 지금 3학년인데 최대 몇 학점까지 미리 담아둘 수 있나요?
학점 이월 한 학기에 몇 점까지 가능한가요
학점 이월로 한 학기에 22학점 들을 수 있나요
국가근로장학생 지원 자격
국가근로장학생 휴학생도 지원 가능한가요
국가근로장학생 선발 조건
국가근로장학생 성적 조건, 성적 제한 있나요
장학금 수혜내역 어디서 확인하나요
장학금 수혜내역 어디서 확인
외국어우수장학금 지급 안내
외국어우수장학금 선정 커트라인
외국어우수장학금 한 학기에 2개 영역(ex.토익 + JLPT) 선발 가능한가요?
사회복지학과 동계 실습 신청 기간
공부 잘하는 방법
사회복지학과 실습 전 필수 과목 리스트
소프트웨어 전공 실습 실습처 리스트
수강신청기간은 언제인가요?
등록금납부기간은 언제부터 언제까지인가요?
졸업요건
학교에서 지원하는 취업 프로그램?
계절학기 수강신청 기간?
상반기 삼성 공채 취업 스터디
창업 노하우
안녕하세요 저는 공대에 재학중인 학생입니다. 창업에 관심이 있는데 학교에서 지원해주는 제도가 있나요?
안녕하세요 저는 현재 4학년 1학기 재학중입니다. 다음 학기인 2학기에 창업과 관련해서 휴학을 하고 싶은데 내야 할 서류가 있나요?
안녕하세요 저는 현재 4학년 1학기 재학중입니다. 다음 학기인 2학기에 창업과 관련해서 휴학을 하고 싶은데 내야 할 학사 관련 서류가 있나요?
안녕하세요 저는 현재 4학년 1학기 재학중입니다. 다음 학기인 2학기에 창업을 하고 싶습니다. 어디로 문의드리면 되나요?
강남대학교 조교 모집
강남대 교수 초빙
국가에서 주최하는 미국 어학 연수 프로그램
국가에서 주최하는 미국 어학 연수 프로그램이 궁금합니다. 그리고 해외 인턴십도 같이 연계가 되었으면 좋겠어요
강남대 졸업생이 참여할 수 있는 취업 프로그램
강남대 재학생이 참여할 수 있는 진로 탐색 프로그램
강남대학교의 2023년의 취업 통계가 궁금합니다.
강남대학교에서 취업한 선배에게 취업 관련 도움을 받을 수 있는 방법은 무엇이 있나요?
안녕하세요 저는 현재 4학년 1학기 재학중입니다. 다음 학기인 2학기에 창업과 관련해서 휴학을 하고 싶은데 내야 할 서류가 있나요? 학번은 201902438입니다. 서류 제출 시 방문을 꼭 해야 하는 지도 궁금합니다.
안녕하세요 저는 현재 4학년 1학기 재학 중입니다. 다음 학기인 2학기에 창업과 관련해서 휴학하고 싶은데 내야 할 서류가 있나요? 학번은 201902438입니다. 서류 제출 시 방문을 꼭 해야 하는 지도 궁금합니다.
안녕하세요 저는 현재 4학년 1학기 재학중입니다. 다음 학기인 2학기에 창업과 관련해서 휴학을 하고 싶은데 내야 할 서류가 있나요? 학번은 201902438입니다. 서류 제출 시 방문을 꼭 해야 하는 지도 궁금합니다. 혹시 저처럼 창업 때문에 휴학하는 학생이 더 있나요?
안녕하세요 저는 현재 4학년 1학기 재학중입니다. 다음 학기인 2학기에 창업과 관련해서 휴학을 하고 싶은데 내야 할 서류가 있나요? 학번은 201902438입니다. 혹시 저처럼 창업 때문에 휴학하는 학생이 더 있나요?
취업 지원 제도
학사 정보
안녕하세요 제가 졸업요건을 보려하는데 19년도 경제세무학과 입학입니다. 근데 과이름이 바뀌면서 군복학후 정경학부 세무학전공으로 변경하였는데 그러면 졸업요건이 19년도 기준인지 21년도 기준인지 궁금합니다.
23년 수강 신청
더체인지 신청기간
학습공동체 스터디단
20학번 졸업학점
일본취업 하는 방법 전공은 소프트웨어
논문 투고 지원사업
강남대 도서관 위치
토익 공부
교내 상담소
중소기업 공고
사회복지 분야 취업 설명회
무료 토익 특강은 없나요?
4 changes: 2 additions & 2 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ spring:

jpa:
hibernate:
ddl-auto: validate #프로젝트 재시작할떄마다 DB 초기화(create)되는것이 아닌 업데이트(코드의 변경사항를 DB에 업데이트) => validate(현재 코드가 DB 스키마와 일치하는지 검증해서 일치하면 시작)
ddl-auto: validate #update:프로젝트 재시작할떄마다 DB 초기화(create)되는것이 아닌 업데이트(코드의 변경사항를 DB에 업데이트) => validate(현재 코드가 DB 스키마와 일치하는지 검증해서 일치하면 시작)
properties:
hibernate:
#dialect: org.hibernate.dialect.MySQLDialect
Expand All @@ -16,7 +16,7 @@ spring:
database-platform: org.hibernate.dialect.MySQLDialect #hibernate.dialect vs database-platform

messages:
basename: messages, names, errors #국제화 파일들
basename: errors #국제화 파일들
h2:
console:
enabled: true
Expand Down
32 changes: 32 additions & 0 deletions src/main/resources/templates/survey/surveyLogin.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{fragments/header :: header}">
</head>

<body class="d-flex justify-content-center align-items-center vh-100 flex-column"> <!-- 여기에 flex-column 추가 -->
<div class="w-50">
<div class="card mt-4">
<div class="card-body">
<p class="text-center">* 하이룽~</p>
<p class="text-center">* 설문조사 열심히해~~ 대충하면 꿀밤</p>
</div>
</div>
</div>

<div class="w-50">
<h3 class="text-center mb-4">설문조사 로그인</h3>
<form action="#" th:action="@{/survey/login}" method="post">
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
<div class="mb-3">
<label for="username" class="form-label">아이디:</label>
<input type="text" class="form-control" id="username" name="username" required minlength="1" maxlength="100">
</div>
<div class="mb-3">
<label for="password" class="form-label">비밀번호:</label>
<input type="password" class="form-control" id="password" name="password" required minlength="1" maxlength="100">
</div>
<button type="submit" class="btn btn-primary w-100">로그인</button>
</form>
</div>
</body>
</html>

0 comments on commit 94d0efe

Please sign in to comment.