Skip to content

Commit

Permalink
Merge branch 'login' into 'develop'
Browse files Browse the repository at this point in the history
Feat: 로그인 기능 추가

See merge request s08-blockchain-contract-sub2/S08P22C209!2
  • Loading branch information
keeeeeey committed Mar 20, 2023
2 parents 5e058ad + 9c238fb commit ae834b3
Show file tree
Hide file tree
Showing 13 changed files with 175 additions and 6 deletions.
3 changes: 3 additions & 0 deletions backend/apigateway-service/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ dependencies {

// JsonWebToken
implementation group: 'io.jsonwebtoken', name: 'jjwt', version: '0.9.1'

// Jaxb-api
implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.2.4'
}

dependencyManagement {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ spring:
- id: user-service
uri: lb://USER-SERVICE
predicates:
- Path=/user-service/signup
- Path=/user-service/join
- Method=POST
filters:
- RemoveRequestHeader=Cookie
Expand Down
2 changes: 1 addition & 1 deletion backend/user-service/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ ext {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
// implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
implementation 'org.jetbrains:annotations:23.0.0'
compileOnly 'org.projectlombok:lombok'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.example.userservice.config;

import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

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

private final Environment env;

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
String IpAddress = env.getProperty("gateway.ip");

http
.httpBasic().disable()
.csrf().disable()
.authorizeRequests()
.antMatchers("/error/**").permitAll()
.antMatchers("/h2-console/**").permitAll()
.antMatchers("/**")
.access("hasIpAddress('" + IpAddress + "')")
.and()
.headers().frameOptions().disable();
return http.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package com.example.userservice.controller;

import com.example.userservice.dto.LoginRequestDto;
import com.example.userservice.dto.SignUpRequestDto;
import com.example.userservice.dto.TokenResponseDto;
import com.example.userservice.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;

@RestController
@RequiredArgsConstructor
@RequestMapping("/")
Expand All @@ -20,13 +24,18 @@ public String welcome() {
}

@GetMapping("/welcome/auth")
public String welcomeAuth() {
return "jwt welcome";
public String welcomeAuth(HttpServletRequest request) {
return request.getHeader("userId");
}

@PostMapping("/signup")
@PostMapping("/join")
public ResponseEntity<String> createUser(@RequestBody SignUpRequestDto requestDto) {
userService.createUser(requestDto);
return ResponseEntity.status(HttpStatus.CREATED).body("회원가입 성공");
}

@PostMapping("/login")
public ResponseEntity<TokenResponseDto> login(@RequestBody LoginRequestDto requestDto) {
return ResponseEntity.status(HttpStatus.CREATED).body(userService.login(requestDto));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,12 @@ public class SignUpRequestDto {
@NotNull(message = "Password cannot be null")
@Size(min = 8, message = "Password must be equal or grater than 8 characters")
private String password;

@NotNull(message = "Nickname cannot be null")
@Size(min = 2, message = "Nickname not be less than two characters")
private String nickname;

private String github;

private String baekjoon;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.example.userservice.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class TokenResponseDto {

private String accessToken;

private String refreshToken;
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,21 @@ public class User {
@Column(nullable = false)
private String password;

@Column(nullable = false, length = 20, unique = true)
private String nickname;

private String github;

private String baekjoon;

public static User from(SignUpRequestDto requestDto) {
return User.builder()
.email(requestDto.getEmail())
.name(requestDto.getName())
.password(new BCryptPasswordEncoder().encode(requestDto.getPassword()))
.nickname(requestDto.getNickname())
.github(requestDto.getGithub())
.baekjoon(requestDto.getBaekjoon())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,8 @@
import com.example.userservice.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByEmail(String email);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.example.userservice.security;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Base64;
import java.util.Date;

@Component
public class JWTUtil {

// 암호화할 때 필요한 비밀 키(secret key)
@Value("${token.secret}")
private String secretKey;

// 토큰 유효시간 60분
private Long accessTokenValidTime = 60 * 60 * 1000L;

// secretKey 객체 초기화, Base64로 인코딩
@PostConstruct
protected void init() {
secretKey = Base64.getEncoder().encodeToString(secretKey.getBytes());
}

public String createToken(String email) {
Claims claims = Jwts.claims().setSubject(email);
Date now = new Date();
return Jwts.builder()
.setClaims(claims)
.setIssuedAt(now)
.setExpiration(new Date(now.getTime() + accessTokenValidTime))
.signWith(SignatureAlgorithm.HS256, secretKey)
.compact();
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package com.example.userservice.service;

import com.example.userservice.dto.LoginRequestDto;
import com.example.userservice.dto.SignUpRequestDto;
import com.example.userservice.dto.TokenResponseDto;

public interface UserService {
void createUser(SignUpRequestDto requestDto);

TokenResponseDto login(LoginRequestDto requestDto);
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package com.example.userservice.service;

import com.example.userservice.dto.LoginRequestDto;
import com.example.userservice.dto.SignUpRequestDto;
import com.example.userservice.dto.TokenResponseDto;
import com.example.userservice.entity.User;
import com.example.userservice.repository.UserRepository;
import com.example.userservice.security.JWTUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

@Service
Expand All @@ -12,9 +18,32 @@ public class UserServiceImpl implements UserService{

private final UserRepository userRepository;

private final PasswordEncoder passwordEncoder;

private final JWTUtil jwtUtil;

@Override
public void createUser(SignUpRequestDto requestDto) {
User user = User.from(requestDto);
userRepository.save(user);
}

@Override
public TokenResponseDto login(LoginRequestDto requestDto) {
String email = requestDto.getEmail();
String password = requestDto.getPassword();

User user = userRepository.findByEmail(email).orElseThrow(() -> new UsernameNotFoundException(""));

if (!passwordEncoder.matches(password, user.getPassword())) {
throw new UsernameNotFoundException("");
}

String accessToken = jwtUtil.createToken(email);

return TokenResponseDto.builder()
.accessToken(accessToken)
.refreshToken("refreshToken")
.build();
}
}
5 changes: 4 additions & 1 deletion backend/user-service/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,7 @@ logging:

token:
secret: dyAeHubOOc8KaOfYB6XEQoEj1QzRlVgtjNL8PYs1A1tymZvvqkcEU7L1imkKHeDa
expiration_time: 864000000
# expiration_time: 864000000

gateway:
ip: 192.168.100.144

0 comments on commit ae834b3

Please sign in to comment.