Skip to content

Commit

Permalink
feat: OAuth 관련 부족한 클래스 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
gitchannn committed Nov 1, 2023
1 parent b68295d commit 0b70ede
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import org.springframework.stereotype.Service;
import sallange.server.auth.OAuthProvider;
import sallange.server.auth.client.OAuthInfoResponse;
import sallange.server.auth.client.UserOAuthClient;
import sallange.server.auth.client.OAuthClient;
import sallange.server.auth.util.OAuthLoginParams;

import java.util.List;
Expand All @@ -21,22 +21,22 @@ public class UserOAuthService {
private final String baseUri;
private final String apiUri;
private final String redirectUri;
private final Map<OAuthProvider, UserOAuthClient> clients;
private final Map<OAuthProvider, OAuthClient> clients;

public UserOAuthService(
@Value("${oauth.kakao.client-id}") String clientId,
@Value("${oauth.kakao.redirect-uri}") String redirectUri,
@Value("${oauth.kakao.url.auth}") String baseUri,
@Value("${oauth.kakao.url.api}") String apiUri,
List<UserOAuthClient> clients
List<OAuthClient> clients
) {
this.clientId = clientId;
this.redirectUri = redirectUri;
this.baseUri = baseUri;
this.apiUri = apiUri;
this.clients = clients.stream().collect(
Collectors.toUnmodifiableMap(
UserOAuthClient::oAuthProvider,
OAuthClient::oAuthProvider,
Function.identity()
)
);
Expand All @@ -51,7 +51,7 @@ public String loginRedirectUri() {
}

public OAuthInfoResponse request(final OAuthLoginParams params) {
UserOAuthClient client = clients.get(params.oAuthProvider());
OAuthClient client = clients.get(params.oAuthProvider());
String accessToken = client.requestAccessToken(params);

return client.requestOauthInfo(accessToken);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package sallange.server.auth.client;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import sallange.server.auth.OAuthProvider;
import sallange.server.auth.util.OAuthLoginParams;

@RequiredArgsConstructor
@Profile("!test")
@Component
public class KakaoApiClient implements OAuthClient {

private static final String GRANT_TYPE = "authorization_code";

@Value("${oauth.kakao.url.auth}")
private String authUrl;

@Value("${oauth.kakao.url.api}")
private String apiUrl;

@Value("${oauth.kakao.client-id}")
private String clientId;

@Value("${oauth.kakao.redirect-uri}")
private String redirectUri;

private final RestTemplate restTemplate;
private final ObjectMapper objectMapper;

@Override
public OAuthProvider oAuthProvider() {
return OAuthProvider.KAKAO;
}

@Override
public String requestAccessToken(final OAuthLoginParams params) {
String url = authUrl + "/oauth/token";

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

final MultiValueMap<String, String> body = params.makeBody();
body.add("grant_type", GRANT_TYPE);
body.add("client_id", clientId);
body.add("redirect_uri", redirectUri);

final HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(body, headers);

KakaoTokens response = restTemplate.postForObject(url, request, KakaoTokens.class);

assert response != null;
return response.getAccessToken();
}

@Override
public OAuthInfoResponse requestOauthInfo(final String accessToken) {
String url = apiUrl + "/v2/user/me";

HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
httpHeaders.setBearerAuth(accessToken);

HttpEntity<?> request = new HttpEntity<>(null, httpHeaders);

ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);
String responseBody = response.getBody();

try {
return objectMapper.readValue(responseBody, KakaoInfoResponse.class);
} catch (JsonProcessingException e) {
throw new RuntimeException("[ERROR] KakaoInfoResponse로 직렬화에 실패했습니다");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package sallange.server.auth.client;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import sallange.server.auth.OAuthProvider;

@Getter
@JsonIgnoreProperties(ignoreUnknown = true)
public class KakaoInfoResponse implements OAuthInfoResponse {

@JsonProperty("id")
private Long id;

@JsonProperty("kakao_account")
private KakaoAccount kakaoAccount;

@Getter
@JsonIgnoreProperties(ignoreUnknown = true)
static class KakaoAccount {

private KakaoProfile profile;
private String email;
}

@Getter
@JsonIgnoreProperties(ignoreUnknown = true)
static class KakaoProfile {

private String nickname;
}

@Override
public String getEmail() {
return kakaoAccount.email;
}

@Override
public String getNickname() {
return kakaoAccount.profile.nickname;
}

@Override
public OAuthProvider getOAuthProvider() {
return OAuthProvider.KAKAO;
}

@Override
public Long getOAuthId() {
return id;
}
}
28 changes: 28 additions & 0 deletions server/src/main/java/sallange/server/auth/client/KakaoTokens.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package sallange.server.auth.client;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class KakaoTokens {

@JsonProperty("access_token")
private String accessToken;

@JsonProperty("token_type")
private String tokenType;

@JsonProperty("refresh_token")
private String refreshToken;

@JsonProperty("expires_in")
private String expiresIn;

@JsonProperty("refresh_token_expires_in")
private String refreshTokenExpiresIn;

@JsonProperty("scope")
private String scope;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import sallange.server.auth.OAuthProvider;
import sallange.server.auth.util.OAuthLoginParams;

public interface UserOAuthClient {
public interface OAuthClient {

OAuthProvider oAuthProvider();

Expand Down
14 changes: 14 additions & 0 deletions server/src/main/java/sallange/server/config/OAuthClientConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package sallange.server.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class OAuthClientConfig {

@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}

0 comments on commit 0b70ede

Please sign in to comment.