From a1034204ab7c17478d84aacb8b7f8d0bb8508cf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=B5=E1=86=AB=E1=84=89?= =?UTF-8?q?=E1=85=A5=E1=86=A8?= Date: Fri, 31 Jan 2020 11:13:12 +0900 Subject: [PATCH] update --- pom.xml | 4 ++ .../vue/config/SecurityConfiguration.java | 3 +- .../UserDetailsAuthenticationProvider.java | 2 +- .../vue/domain/auth/AuthController.java | 28 +++++++++++++ .../vue/domain/auth/AuthException.java | 14 +++++++ .../example/vue/domain/auth/AuthService.java | 19 +++++++++ .../vue/domain/auth/LoginRequestDto.java | 15 +++++++ .../vue/domain/auth/LoginResponseDto.java | 8 ++++ .../com/example/vue/domain/user/User.java | 23 +++++++++-- .../domain/user/UserDetailsServiceImpl.java | 2 + .../vue/domain/user/UserRepository.java | 5 +++ src/main/resources/application.properties | 3 ++ src/main/resources/db/migration/V1__init.sql | 39 +++++++++++++++++++ 13 files changed, 159 insertions(+), 6 deletions(-) rename src/main/java/com/example/vue/{ => config}/security/UserDetailsAuthenticationProvider.java (96%) create mode 100644 src/main/java/com/example/vue/domain/auth/AuthController.java create mode 100644 src/main/java/com/example/vue/domain/auth/AuthException.java create mode 100644 src/main/java/com/example/vue/domain/auth/AuthService.java create mode 100644 src/main/java/com/example/vue/domain/auth/LoginRequestDto.java create mode 100644 src/main/java/com/example/vue/domain/auth/LoginResponseDto.java create mode 100644 src/main/resources/db/migration/V1__init.sql diff --git a/pom.xml b/pom.xml index 9e3e29f..1ddbb9c 100644 --- a/pom.xml +++ b/pom.xml @@ -59,6 +59,10 @@ + + org.flywaydb + flyway-core + org.springframework.security spring-security-test diff --git a/src/main/java/com/example/vue/config/SecurityConfiguration.java b/src/main/java/com/example/vue/config/SecurityConfiguration.java index a14cb12..e821d34 100644 --- a/src/main/java/com/example/vue/config/SecurityConfiguration.java +++ b/src/main/java/com/example/vue/config/SecurityConfiguration.java @@ -1,6 +1,6 @@ package com.example.vue.config; -import com.example.vue.security.UserDetailsAuthenticationProvider; +import com.example.vue.config.security.UserDetailsAuthenticationProvider; import com.example.vue.domain.user.UserDetailsServiceImpl; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; @@ -31,6 +31,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { protected void configure(HttpSecurity http) throws Exception { http.cors().disable() + .csrf().disable() .authorizeRequests() .antMatchers("/auth/login").permitAll() .antMatchers("/auth/register").permitAll() diff --git a/src/main/java/com/example/vue/security/UserDetailsAuthenticationProvider.java b/src/main/java/com/example/vue/config/security/UserDetailsAuthenticationProvider.java similarity index 96% rename from src/main/java/com/example/vue/security/UserDetailsAuthenticationProvider.java rename to src/main/java/com/example/vue/config/security/UserDetailsAuthenticationProvider.java index 396ba18..9a4513f 100644 --- a/src/main/java/com/example/vue/security/UserDetailsAuthenticationProvider.java +++ b/src/main/java/com/example/vue/config/security/UserDetailsAuthenticationProvider.java @@ -1,4 +1,4 @@ -package com.example.vue.security; +package com.example.vue.config.security; import com.example.vue.domain.user.UserDetailsServiceImpl; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/example/vue/domain/auth/AuthController.java b/src/main/java/com/example/vue/domain/auth/AuthController.java new file mode 100644 index 0000000..581ac39 --- /dev/null +++ b/src/main/java/com/example/vue/domain/auth/AuthController.java @@ -0,0 +1,28 @@ +package com.example.vue.domain.auth; + +import lombok.RequiredArgsConstructor; +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 javax.validation.Valid; + +@RestController +@RequestMapping(value = "/auth") +@RequiredArgsConstructor +public class AuthController { + + private final AuthService authService; + + @PostMapping(value = "/login") + public LoginResponseDto login(@RequestBody @Valid LoginRequestDto loginRequestDto) { + authService.login(loginRequestDto); + return null; + } + + @PostMapping(value = "/register") + public void register() { + + } +} diff --git a/src/main/java/com/example/vue/domain/auth/AuthException.java b/src/main/java/com/example/vue/domain/auth/AuthException.java new file mode 100644 index 0000000..28e1c36 --- /dev/null +++ b/src/main/java/com/example/vue/domain/auth/AuthException.java @@ -0,0 +1,14 @@ +package com.example.vue.domain.auth; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +public class AuthException { + + @ResponseStatus(HttpStatus.BAD_REQUEST) + public static class NoExistEmail extends RuntimeException { + public NoExistEmail(String email) { + super("존재하지 않는 이메일입니다. [email=" + email + "]"); + } + } +} diff --git a/src/main/java/com/example/vue/domain/auth/AuthService.java b/src/main/java/com/example/vue/domain/auth/AuthService.java new file mode 100644 index 0000000..db57dfb --- /dev/null +++ b/src/main/java/com/example/vue/domain/auth/AuthService.java @@ -0,0 +1,19 @@ +package com.example.vue.domain.auth; + +import com.example.vue.domain.user.UserRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class AuthService { + + private final UserRepository userRepository; + + public void login(LoginRequestDto loginRequestDto) { + String email = loginRequestDto.getEmail(); + if (userRepository.findByEmail(email).size() < 1) { + throw new AuthException.NoExistEmail(email); + } + } +} diff --git a/src/main/java/com/example/vue/domain/auth/LoginRequestDto.java b/src/main/java/com/example/vue/domain/auth/LoginRequestDto.java new file mode 100644 index 0000000..d7b803d --- /dev/null +++ b/src/main/java/com/example/vue/domain/auth/LoginRequestDto.java @@ -0,0 +1,15 @@ +package com.example.vue.domain.auth; + +import lombok.Data; + +import javax.validation.constraints.NotNull; + +@Data +public class LoginRequestDto { + + @NotNull + private String email; + + @NotNull + private String password; +} diff --git a/src/main/java/com/example/vue/domain/auth/LoginResponseDto.java b/src/main/java/com/example/vue/domain/auth/LoginResponseDto.java new file mode 100644 index 0000000..a00bfd8 --- /dev/null +++ b/src/main/java/com/example/vue/domain/auth/LoginResponseDto.java @@ -0,0 +1,8 @@ +package com.example.vue.domain.auth; + +import lombok.Data; + +@Data +public class LoginResponseDto { + private String token; +} diff --git a/src/main/java/com/example/vue/domain/user/User.java b/src/main/java/com/example/vue/domain/user/User.java index 6c3deb0..2c1477e 100644 --- a/src/main/java/com/example/vue/domain/user/User.java +++ b/src/main/java/com/example/vue/domain/user/User.java @@ -1,13 +1,28 @@ package com.example.vue.domain.user; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; + +import javax.persistence.*; +import java.time.LocalDateTime; @Entity +@NamedQuery(name = "findByEmail", query = "select u from User u where u.email = :email") public class User { @Id @GeneratedValue - Long id; + private Long id; + + @Column(name = "email") + private String email; + + @Column(name = "name") + private String name; + + @CreatedDate + private LocalDateTime createdAt; + + @LastModifiedDate + private LocalDateTime updatedAt; } diff --git a/src/main/java/com/example/vue/domain/user/UserDetailsServiceImpl.java b/src/main/java/com/example/vue/domain/user/UserDetailsServiceImpl.java index 55cd2bf..e2f630c 100644 --- a/src/main/java/com/example/vue/domain/user/UserDetailsServiceImpl.java +++ b/src/main/java/com/example/vue/domain/user/UserDetailsServiceImpl.java @@ -3,7 +3,9 @@ package com.example.vue.domain.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.stereotype.Service; +@Service public class UserDetailsServiceImpl implements UserDetailsService { @Override diff --git a/src/main/java/com/example/vue/domain/user/UserRepository.java b/src/main/java/com/example/vue/domain/user/UserRepository.java index c788fa0..121fef3 100644 --- a/src/main/java/com/example/vue/domain/user/UserRepository.java +++ b/src/main/java/com/example/vue/domain/user/UserRepository.java @@ -4,6 +4,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; import javax.persistence.EntityManager; +import java.util.List; @Repository @RequiredArgsConstructor @@ -16,4 +17,8 @@ public class UserRepository { return user; } + public List findByEmail(String email) { + return em.createNamedQuery("findByEmail", User.class).setParameter("email", email).getResultList(); + } + } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 4aab95b..839fb06 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,9 +1,12 @@ spring.datasource.password=1111 spring.datasource.username=root spring.datasource.url=jdbc:mysql://localhost:3307/blog?serverTimezone=Asia/Seoul + spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=validate spring.jpa.hibernate.use-new-id-generator-mappings=false spring.jpa.properties.hibernate.format_sql=true +server.error.include-stacktrace=never + server.port=7070 \ No newline at end of file diff --git a/src/main/resources/db/migration/V1__init.sql b/src/main/resources/db/migration/V1__init.sql new file mode 100644 index 0000000..3bb9884 --- /dev/null +++ b/src/main/resources/db/migration/V1__init.sql @@ -0,0 +1,39 @@ +CREATE TABLE user ( + id bigint unsigned NOT NULL AUTO_INCREMENT, + created_at datetime(6) DEFAULT NULL, + email varchar(255) DEFAULT NULL, + password varchar(255) DEFAULT NULL, + updated_at datetime(6) DEFAULT NULL, + name varchar(255) DEFAULT NULL, + + PRIMARY KEY (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE article ( + id bigint unsigned NOT NULL AUTO_INCREMENT, + content varchar(255) DEFAULT NULL, + created_at datetime(6) DEFAULT NULL, + title varchar(255) DEFAULT NULL, + updated_at datetime(6) DEFAULT NULL, + user_id bigint unsigned DEFAULT NULL, + + PRIMARY KEY (id), + KEY fk_article_user_id (user_id), + CONSTRAINT fk_article_user_id FOREIGN KEY (user_id) REFERENCES user (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE authority ( + id bigint unsigned NOT NULL AUTO_INCREMENT, + user_id bigint unsigned NOT NULL, + authority varchar(255) NOT NULL, + + PRIMARY KEY (id), + KEY fk_authority_user_id (user_id), + CONSTRAINT fk_authority_user_id FOREIGN KEY (user_id) REFERENCES user (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE hibernate_sequence ( + next_val bigint unsigned DEFAULT NULL, + sequence_name VARCHAR(255) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +