728x90
반응형
index
<!DOCTYPE html>
<!-- 회원가입 뷰 -> sign-up form을 만들어야 한다. 닉네임 이메일 비밀번호-->
<!-- 타임리프 네임스페이스 설정-->
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<meta charset="UTF-8">
<title>Demo</title>
<!-- CSS only-> npm으로 이전
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous">
-->
<link rel="stylesheet" href="/node_modules/bootstrap/dist/css/bootstrap.min.css" />
<style>
.container {
max-width: 100%;
}
</style>
</head>
<body class="bg-light">
<!-- 네비바 만들기-->
<nav class="navbar navbar-expand-sm navbar-dark bg-dark">
<!-- 배너-->
<a class="navbar-brand" href="/" th:href="@{/}">
<!--@는 경로설정인데 이 경우엔 root경로 -->
<img src="/images/logo_sm.png" width="30" height="30">
</a>
<!-- 네비게이션 아이템 검색 창-->
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent">
<span class="navbar-toggler-icon"> </span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<!-- 스터디 찾기 버튼 href="#" th:href="은 타임리프 동작 X와 동작시-->
<form th:action="@{/search/study}" class="form-inline" method="get" action="#">
<input class="form-control mr-sm-2" name="keyword" placeholder="스터디 찾기" type="search" />
</form>
</li>
</ul>
<!-- 로그인, 가입 버튼 href="#" th:href="은 타임리프 동작 X와 동작시-->
<ul class="navbar-nav justify-content-end">
<li class="nav-item" sec:authorize="!isAuthenticated()">
<a class="nav-link" th:href="@{/login}">로그인</a>
</li>
<li class="nav-item" sec:authorize="!isAuthenticated()">
<a class="nav-link" th:href="@{/sign-up}">가입</a>
</li>
<li class="nav-item" sec:authorize="isAuthenticated()">
<a class="nav-link" th:href="@{/notifications}">
알림
</a>
</li>
<li class="nav-item" sec:authorize="isAuthenticated()">
<a class="nav-link btn btn-outline-primary" th:href="@{/new-study}">
스터디 개설
</a>
</li>
<li class="nav-item dropdown" sec:authorize="isAuthenticated()">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown"
aria-expanded="false">
프로필
</a>
<div class="dropdown-menu dropdown-menu-sm-right" aria-labelledby="userDropdown">
<ul>
<h6 class="dropdown-header">
<span sec:authentication="name">Username</span>
</h6>
<a class="dropdown-item" th:href="@{'/profile/' + ${#authentication.name}}">프로필</a>
<a class="dropdown-item">스터디</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" th:href="@{'/settings/profile'}">설정</a>
<form class="form-inline my-2 my-lg-0" action="#" th:action="@{/logout}" method="post">
<button class="dropdown-item" type="submit">로그아웃</button>
</form>
</ul>
</div>
</li>
</ul>
</div>
</nav>
<!-- index html-->
<div class="container">
<div class="py-5 text-center">
<h2>데모</h2>
</div>
<footer th:fragment="footer">
<div class="row justify-content-center">
<img class="mb-2" src="/images/logo_long_kr.jpg" alt="" width="100">
<small class="d-block mb-3 text-muted">© 2020</small>
</div>
</footer>
</div>
<!--npm 으로 이전
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js"
integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa"
crossorigin="anonymous">
-->
<script src="/node_modules/jquery/dist/jquery.min.js"></script>
<script src="/node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
</script>
<!--needs-validation을 가지는 폼을 가져와 submit 이벤트 발생시 유효여부 검증, 유효하지 않으면, submit안되도록 처리 -->
<!--유효하면 was-validated에 추가 -> input의 required을 기반으로 처리-->
<script type="application/javascript" th:fragment="form-validation">
</script>
</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.3</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.demo</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Srping Boot Demo</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.thymeleaf.extras/thymeleaf-extras-springsecurity5 -->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mockito/mockito-core -->
<!-- https://mvnrepository.com/artifact/org.mockito/mockito-all -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.8.0</version>
<configuration>
<nodeVersion>v4.6.0</nodeVersion>
<workingDirectory>src/main/resources/static</workingDirectory>
</configuration>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<phase>generate-resources</phase>
</execution>
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<arguments>install</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
gitignore
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
##NPM##
src/main/resources/static/node_modules
src/main/resources/static/node
SecurityConfig
package com.demo.config;
import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.web.SecurityFilterChain;
import lombok.RequiredArgsConstructor;
//회원가입을 위한 시큐리티 수동 설정
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
// private final AccountService accountService;
// private final DataSource dataSource;
/**
* Spring Security 5.7.x 부터 WebSecurityConfigurerAdapter 는 Deprecated. ->
* SecurityFilterChain, WebSecurityCustomizer 를 상황에 따라 빈으로 등록해 사용한다.
*/
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// 오버라이딩을 통해 원하는 요청은 시큐리티 체크를 하지 않도록 설정
return http.authorizeRequests()
// 모듈에서 걸러내야 하는 요청들
.mvcMatchers("/", "/login", "/sign-up", "/check-email", "/check-email-token", "/email-login",
"/check-email-login", "login-link")
.permitAll()
// .mvcMatchers("/", "/login", "/sign-up", "/check-email", "/check-email-token",
// "/email-login", "/check-email-login", "login-link", "/profile/*").permitAll()
// -> 프로필에 붙어있는 모든 요청은 get만 허용
.mvcMatchers(HttpMethod.GET, "/profile/*").permitAll()
// 그외에 나머지 요청의 경우 모두 로그인이 필요하다.
.anyRequest().authenticated().and().build();
//
// .and()
// .formLogin().loginPage("/login").permitAll()
//
// .and()
// .logout().logoutSuccessUrl("/")
//
// .and()
// .rememberMe().userDetailsService(accountService).tokenRepository(tokenRepository())
// .and().build();
//
}
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
// static리소스도 요청을 거부하지 않는다.
return (web) -> web.ignoring().mvcMatchers("/node_modules/**")
.requestMatchers(PathRequest.toStaticResources().atCommonLocations());
}
}
728x90
반응형
'Server Programming > Spring Boot Full-Stack Programming' 카테고리의 다른 글
[스프링 풀스택 클론 코딩] 타임리프의 fragment 기능 (0) | 2022.08.29 |
---|---|
[스프링 풀스택 클론 코딩 - 회원가입] (1-14) 뷰 중복 코드 제거 (0) | 2022.08.29 |
[스프링 풀스택 클론 코딩] Node.js (npm) 연동 (0) | 2022.08.29 |
[스프링 풀스택 클론 코딩] 로그인 여부에 따른 네비게이션 메뉴 구성 (0) | 2022.08.29 |
[스프링 풀스택 클론 코딩 - 회원가입] (1-12) 회원 가입 메인 네비게이션 메뉴 (0) | 2022.08.29 |