#24 simple sns: 로그인 api 구현
This commit is contained in:
@@ -25,6 +25,11 @@ dependencies {
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||
compileOnly 'org.projectlombok:lombok'
|
||||
runtimeOnly 'org.postgresql:postgresql'
|
||||
|
||||
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
|
||||
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
|
||||
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
|
||||
|
||||
annotationProcessor 'org.projectlombok:lombok'
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
testImplementation 'org.springframework.security:spring-security-test'
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.example.sns.controller;
|
||||
|
||||
import com.example.sns.controller.request.UserJoinRequest;
|
||||
import com.example.sns.controller.request.UserLoginRequest;
|
||||
import com.example.sns.controller.response.Response;
|
||||
import com.example.sns.controller.response.UserJoinResponse;
|
||||
import com.example.sns.controller.response.UserLoginResponse;
|
||||
import com.example.sns.model.User;
|
||||
import com.example.sns.service.UserService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -24,4 +26,10 @@ public class UserController {
|
||||
|
||||
return Response.success(UserJoinResponse.fromUser(user));
|
||||
}
|
||||
|
||||
@PostMapping("/login")
|
||||
public Response<UserLoginResponse> login(@RequestBody UserLoginRequest request) {
|
||||
String token = userService.login(request.getUsername(), request.getPassword());
|
||||
return Response.success(new UserLoginResponse(token));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.example.sns.controller.response;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public class UserLoginResponse {
|
||||
|
||||
private String token;
|
||||
}
|
||||
@@ -9,6 +9,8 @@ import org.springframework.http.HttpStatus;
|
||||
public enum ErrorCode {
|
||||
|
||||
DUPLICATED_USER_NAME(HttpStatus.CONFLICT, "Username is duplicated."),
|
||||
USER_NOT_FOUND(HttpStatus.NOT_FOUND, "User not founded."),
|
||||
INVALID_PASSWORD(HttpStatus.UNAUTHORIZED, "Password is invalid."),
|
||||
INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "Internal server error.")
|
||||
|
||||
;
|
||||
|
||||
@@ -12,12 +12,17 @@ public class SnsApplicationException extends RuntimeException {
|
||||
private ErrorCode errorCode;
|
||||
private String message;
|
||||
|
||||
public SnsApplicationException(ErrorCode errorCode) {
|
||||
this.errorCode = errorCode;
|
||||
this.message = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
if (message==null) {
|
||||
return errorCode.getMessage();
|
||||
}
|
||||
|
||||
return String.format("$s, $s", errorCode.getMessage(), message);
|
||||
return String.format("%s, %s", errorCode.getMessage(), message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,11 +5,15 @@ import com.example.sns.exception.SnsApplicationException;
|
||||
import com.example.sns.model.User;
|
||||
import com.example.sns.model.entity.UserEntity;
|
||||
import com.example.sns.repository.UserEntityRepository;
|
||||
import com.example.sns.util.JwtTokenUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import static com.example.sns.exception.ErrorCode.*;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class UserService {
|
||||
@@ -17,12 +21,18 @@ public class UserService {
|
||||
private final UserEntityRepository userEntityRepository;
|
||||
private final BCryptPasswordEncoder encoder;
|
||||
|
||||
@Value("${jwt.secret-key}")
|
||||
private String secretKey;
|
||||
|
||||
@Value("${jwt.token.expired-time-ms}")
|
||||
private Long expiredTimeMs;
|
||||
|
||||
@Transactional
|
||||
public User join(String username, String password){
|
||||
public User join(String username, String password) {
|
||||
|
||||
// username 확인
|
||||
userEntityRepository.findByUsername(username).ifPresent(it -> {
|
||||
throw new SnsApplicationException(ErrorCode.DUPLICATED_USER_NAME, String.format("%s is duplicated", username));
|
||||
throw new SnsApplicationException(DUPLICATED_USER_NAME, String.format("%s is duplicated", username));
|
||||
});
|
||||
|
||||
// 회원가입 진행
|
||||
@@ -34,13 +44,17 @@ public class UserService {
|
||||
public String login(String username, String password) {
|
||||
|
||||
// 회원가입 여부 체크
|
||||
UserEntity userEntity = userEntityRepository.findByUsername(username).orElseThrow(SnsApplicationException::new);
|
||||
UserEntity userEntity = userEntityRepository.findByUsername(username)
|
||||
.orElseThrow(
|
||||
() -> new SnsApplicationException(USER_NOT_FOUND, String.format("%s not founded", username))
|
||||
);
|
||||
|
||||
// 비밀번호 체크
|
||||
if (!userEntity.getPassword().equals(password)) {
|
||||
throw new SnsApplicationException();
|
||||
if (!encoder.matches(password, userEntity.getPassword())) {
|
||||
throw new SnsApplicationException(INVALID_PASSWORD);
|
||||
}
|
||||
|
||||
return "";
|
||||
// 토큰 생성
|
||||
return JwtTokenUtils.generateToken(username, secretKey, expiredTimeMs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.example.sns.util;
|
||||
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
import io.jsonwebtoken.security.Keys;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.Key;
|
||||
import java.util.Date;
|
||||
|
||||
public class JwtTokenUtils {
|
||||
|
||||
public static String generateToken(String username, String key, long expiredTimeMs) {
|
||||
Claims claims = Jwts.claims();
|
||||
claims.put("username", username);
|
||||
|
||||
return Jwts.builder()
|
||||
.setClaims(claims)
|
||||
.setIssuedAt(new Date(System.currentTimeMillis()))
|
||||
.setExpiration(new Date(System.currentTimeMillis() + expiredTimeMs))
|
||||
.signWith(getKey(key), SignatureAlgorithm.HS256)
|
||||
.compact();
|
||||
}
|
||||
|
||||
private static Key getKey(String key) {
|
||||
byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
|
||||
return Keys.hmacShaKeyFor(keyBytes);
|
||||
}
|
||||
}
|
||||
@@ -21,3 +21,7 @@ spring:
|
||||
platform: postgres
|
||||
driver-class-name: org.postgresql.Driver
|
||||
|
||||
jwt:
|
||||
secret-key: simple_sns_application_secret_key
|
||||
token:
|
||||
expired-time-ms: 2592000000
|
||||
Reference in New Issue
Block a user