login success
This commit is contained in:
19
pom.xml
19
pom.xml
@@ -59,6 +59,25 @@
|
|||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-api</artifactId>
|
||||||
|
<version>0.10.7</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-impl</artifactId>
|
||||||
|
<version>0.10.7</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-orgjson</artifactId>
|
||||||
|
<version>0.10.7</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.flywaydb</groupId>
|
<groupId>org.flywaydb</groupId>
|
||||||
<artifactId>flyway-core</artifactId>
|
<artifactId>flyway-core</artifactId>
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ package com.example.vue.config;
|
|||||||
|
|
||||||
import com.example.vue.config.security.UserDetailsAuthenticationProvider;
|
import com.example.vue.config.security.UserDetailsAuthenticationProvider;
|
||||||
import com.example.vue.domain.user.UserDetailsServiceImpl;
|
import com.example.vue.domain.user.UserDetailsServiceImpl;
|
||||||
|
import com.example.vue.util.JwtUtil;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.security.authentication.AuthenticationProvider;
|
import org.springframework.security.authentication.AuthenticationProvider;
|
||||||
@@ -20,6 +22,9 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
|
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
|
@Value("${jwt.secret}")
|
||||||
|
private String secret;
|
||||||
|
|
||||||
private final UserDetailsServiceImpl userDetailService;
|
private final UserDetailsServiceImpl userDetailService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -50,4 +55,9 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
|
|||||||
public AuthenticationProvider authenticationProvider() {
|
public AuthenticationProvider authenticationProvider() {
|
||||||
return new UserDetailsAuthenticationProvider(userDetailService, bCryptPasswordEncoder());
|
return new UserDetailsAuthenticationProvider(userDetailService, bCryptPasswordEncoder());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public JwtUtil jwtUtil() {
|
||||||
|
return new JwtUtil(secret);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,8 +17,7 @@ public class AuthController {
|
|||||||
|
|
||||||
@PostMapping(value = "/login")
|
@PostMapping(value = "/login")
|
||||||
public LoginResponseDto login(@RequestBody @Valid LoginRequestDto loginRequestDto) {
|
public LoginResponseDto login(@RequestBody @Valid LoginRequestDto loginRequestDto) {
|
||||||
authService.login(loginRequestDto);
|
return authService.login(loginRequestDto);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/register")
|
@PostMapping(value = "/register")
|
||||||
|
|||||||
@@ -11,4 +11,11 @@ public class AuthException {
|
|||||||
super("존재하지 않는 이메일입니다. [email=" + email + "]");
|
super("존재하지 않는 이메일입니다. [email=" + email + "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||||
|
public static class PasswordNotMatched extends RuntimeException {
|
||||||
|
public PasswordNotMatched() {
|
||||||
|
super("패스워드가 일치하지 않습니다.");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,38 @@
|
|||||||
package com.example.vue.domain.auth;
|
package com.example.vue.domain.auth;
|
||||||
|
|
||||||
|
import com.example.vue.domain.user.User;
|
||||||
import com.example.vue.domain.user.UserRepository;
|
import com.example.vue.domain.user.UserRepository;
|
||||||
|
import com.example.vue.util.JwtUtil;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class AuthService {
|
public class AuthService {
|
||||||
|
|
||||||
private final UserRepository userRepository;
|
private final UserRepository userRepository;
|
||||||
|
private final BCryptPasswordEncoder bCryptPasswordEncoder;
|
||||||
|
private final JwtUtil jwtUtil;
|
||||||
|
|
||||||
public void login(LoginRequestDto loginRequestDto) {
|
public LoginResponseDto login(LoginRequestDto loginRequestDto) {
|
||||||
String email = loginRequestDto.getEmail();
|
String email = loginRequestDto.getEmail();
|
||||||
if (userRepository.findByEmail(email).size() < 1) {
|
String password = loginRequestDto.getPassword();
|
||||||
|
|
||||||
|
List<User> users = userRepository.findByEmail(email);
|
||||||
|
if (users.size() < 1) {
|
||||||
throw new AuthException.NoExistEmail(email);
|
throw new AuthException.NoExistEmail(email);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
User user = users.get(0);
|
||||||
|
|
||||||
|
if (!bCryptPasswordEncoder.matches(password, user.getPassword())) {
|
||||||
|
throw new AuthException.PasswordNotMatched();
|
||||||
|
}
|
||||||
|
|
||||||
|
String token = jwtUtil.createToken(user.getId(), user.getName(), "ROLE_USER");
|
||||||
|
return new LoginResponseDto(token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,4 +5,8 @@ import lombok.Data;
|
|||||||
@Data
|
@Data
|
||||||
public class LoginResponseDto {
|
public class LoginResponseDto {
|
||||||
private String token;
|
private String token;
|
||||||
|
|
||||||
|
public LoginResponseDto(String token) {
|
||||||
|
this.token = token;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.example.vue.domain.user;
|
package com.example.vue.domain.user;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
import org.springframework.data.annotation.CreatedDate;
|
import org.springframework.data.annotation.CreatedDate;
|
||||||
import org.springframework.data.annotation.LastModifiedDate;
|
import org.springframework.data.annotation.LastModifiedDate;
|
||||||
|
|
||||||
@@ -7,12 +8,16 @@ import javax.persistence.*;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
|
@Getter
|
||||||
@NamedQuery(name = "findByEmail", query = "select u from User u where u.email = :email")
|
@NamedQuery(name = "findByEmail", query = "select u from User u where u.email = :email")
|
||||||
public class User {
|
public class User {
|
||||||
|
|
||||||
@Id @GeneratedValue
|
@Id @GeneratedValue
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
@Column(name = "password")
|
||||||
|
private String password;
|
||||||
|
|
||||||
@Column(name = "email")
|
@Column(name = "email")
|
||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
|
|||||||
63
src/main/java/com/example/vue/util/JwtUtil.java
Normal file
63
src/main/java/com/example/vue/util/JwtUtil.java
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
package com.example.vue.util;
|
||||||
|
|
||||||
|
import io.jsonwebtoken.Claims;
|
||||||
|
import io.jsonwebtoken.JwtBuilder;
|
||||||
|
import io.jsonwebtoken.Jwts;
|
||||||
|
import io.jsonwebtoken.SignatureAlgorithm;
|
||||||
|
import io.jsonwebtoken.security.Keys;
|
||||||
|
|
||||||
|
import java.security.Key;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class JwtUtil {
|
||||||
|
|
||||||
|
private Key key;
|
||||||
|
|
||||||
|
public static long PLUS_MILLS = (1000 * 60 * 60 * 24) * 30L;
|
||||||
|
|
||||||
|
public JwtUtil(String secret) {
|
||||||
|
this.key = Keys.hmacShaKeyFor(secret.getBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String createToken(Long userId, String name, String role) {
|
||||||
|
|
||||||
|
JwtBuilder builder = Jwts.builder()
|
||||||
|
.claim("userId", userId)
|
||||||
|
.claim("name", name)
|
||||||
|
.claim("role", role);
|
||||||
|
|
||||||
|
return builder
|
||||||
|
.signWith(key, SignatureAlgorithm.HS256)
|
||||||
|
.setExpiration(expireTime())
|
||||||
|
.compact();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Date expireTime() {
|
||||||
|
Date expireTime = new Date();
|
||||||
|
expireTime.setTime(expireTime.getTime() + PLUS_MILLS);
|
||||||
|
return expireTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Claims getClaims(String token) {
|
||||||
|
return Jwts.parser()
|
||||||
|
.setSigningKey(key)
|
||||||
|
.parseClaimsJws(token)
|
||||||
|
.getBody();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isUsable(String token) {
|
||||||
|
try {
|
||||||
|
Jwts.parser()
|
||||||
|
.setSigningKey(key)
|
||||||
|
.parseClaimsJws(token)
|
||||||
|
.getBody();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("권한이 유효하지 않습니다.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,4 +9,6 @@ spring.jpa.properties.hibernate.format_sql=true
|
|||||||
|
|
||||||
server.error.include-stacktrace=never
|
server.error.include-stacktrace=never
|
||||||
|
|
||||||
server.port=7070
|
server.port=7070
|
||||||
|
|
||||||
|
jwt.secret=12345678901234567890123456789012
|
||||||
Reference in New Issue
Block a user