Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/main/java/kr/warmlink/application/auth/config/KakaoConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package kr.warmlink.application.auth.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Data
@Configuration
@ConfigurationProperties(prefix = "spring.kakao")
public class KakaoConfig {
private String authorizationUri;
private String tokenUri;
private String userInfoUri;
private String unlinkUri;
private String clientId;
private String clientSecret;
private String adminKey;
private String redirectUri;
private String scope;
}
19 changes: 19 additions & 0 deletions src/main/java/kr/warmlink/application/auth/dto/SignInDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package kr.warmlink.application.auth.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Getter;

public class SignInDto {
@Getter
@AllArgsConstructor
@Schema(name = "SignIn.Response", description = "로그인 응답 DTO")
public static class Response {
private String message;
private String accessToken;

public static Response of(String message, String accessToken) {
return new Response(message, accessToken);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package kr.warmlink.application.auth.service;

import kr.warmlink.application.auth.config.KakaoConfig;
import kr.warmlink.application.auth.dto.SignInDto;
import kr.warmlink.common.jwt.util.JwtProvider;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

@Slf4j
@Service
@RequiredArgsConstructor
public class KakaoOAuthService {

private final KakaoConfig kakaoConfig;
private final JwtProvider jwtProvider;

public ResponseEntity<SignInDto.Response> kakaoSignIn(String code) {
String token = getToken(code);
String email = getEmail(token);

String message = "로그인에 성공하였습니다";
String accessToken = jwtProvider.generateAccessToken(email);

return ResponseEntity.ok(SignInDto.Response.of(message, accessToken));
}

private String getToken(String code) {
RestTemplate restTemplate = new RestTemplate();

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("grant_type", "authorization_code");
params.add("client_id", kakaoConfig.getClientId());
params.add("client_secret", kakaoConfig.getClientSecret());
params.add("redirect_uri", kakaoConfig.getRedirectUri());
params.add("code", code);

log.info("token uri - {}", kakaoConfig.getTokenUri());
HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(params, headers);
ResponseEntity<Map<String, Object>> response = restTemplate.exchange(
kakaoConfig.getTokenUri(),
HttpMethod.POST,
entity,
new ParameterizedTypeReference<Map<String, Object>>() {
}
);

Map<String, Object> tokenInfo = response.getBody();
return (String) tokenInfo.get("access_token");
}

private String getEmail(String token) {
RestTemplate restTemplate = new RestTemplate();

HttpHeaders headers = new HttpHeaders();
headers.setBearerAuth(token);

HttpEntity<String> entity = new HttpEntity<>(headers);
ResponseEntity<Map<String, Object>> response = restTemplate.exchange(
kakaoConfig.getUserInfoUri(),
HttpMethod.GET,
entity,
new ParameterizedTypeReference<Map<String, Object>>() {
}
);

Map<String, Object> userInfo = response.getBody();
Map<String, Object> kakaoAccount = (Map<String, Object>) userInfo.get("kakao_account");
String email = (String) kakaoAccount.get("email");

return email;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

@Data
@Configuration
@ConfigurationProperties(prefix = "jwt")
@ConfigurationProperties(prefix = "spring.jwt")
public class JwtProperties {
private String secret;
private Long accessExpiration;
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/kr/warmlink/presentation/api/AuthApi.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package kr.warmlink.presentation.api;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestParam;

@Tag(name = "[인증 관련 API]", description = "사용자 인증 관련 API")
public interface AuthApi {
@Operation(summary = "사용자 카카오 로그인", description = "사용자의 로그인 및 회원가입을 위한 카카오 로그인 API입니다.")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "로그인 성공"),
@ApiResponse(responseCode = "400", description = "로그인 실패")
})
ResponseEntity<?> signIn(@RequestParam("code") String code);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package kr.warmlink.presentation.controller;

import kr.warmlink.application.auth.service.KakaoOAuthService;
import kr.warmlink.presentation.api.AuthApi;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/auth")
@RequiredArgsConstructor
public class AuthController implements AuthApi {

private final KakaoOAuthService kakaoOAuthService;

@Override
@GetMapping("/sign-in/kakao")
public ResponseEntity<?> signIn(String code) {
return kakaoOAuthService.kakaoSignIn(code);
}

}
Loading