Coding History/Team Project

팀플) AstronomyAPI 연결 시작 (폐기)

BlackBirdIT 2024. 10. 9. 02:50

이제는 Astronomy API를 연결해보자.

여기서 앱 생성해주면 API Key를 주겠지. 나도 처음해봐서 잘 모른다.

이렇게 생성.

음 주는군 이제 이걸 사용하면 된다.

만들었으니 .env에 KEY값을 환경변수로 저장해주고

@Service
public class AstronomyApiService {

    private final String apiKey;
    private final String apiSecret;
    private final String baseUrl;

    private RestTemplate restTemplate = new RestTemplate();

    public AstronomyApiService() {
        // Dotenv로 환경 변수 불러오기
        Dotenv dotenv = Dotenv.configure().load();
        this.apiKey = dotenv.get("ASTRONOMY_API_KEY");
        this.apiSecret = dotenv.get("ASTRONOMY_API_SECRET");
        this.baseUrl = dotenv.get("ASTRONOMY_API_BASE_URL");
    }

    // 특정 위치에서 특정 시간에 대한 천문 이벤트 정보를 가져오는 메서드
    public String getAstronomicalData(double latitude, double longitude, String date) {
        String url = baseUrl + "astronomy?lat=" + latitude + "&long=" + longitude + "&date=" + date;

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.setBasicAuth(apiKey, apiSecret);  // API 키와 시크릿을 사용한 인증

        HttpEntity<String> entity = new HttpEntity<>(headers);

        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);

        if (response.getStatusCode() == HttpStatus.OK) {
            return response.getBody();
        } else {
            throw new RuntimeException("Failed to retrieve astronomical data");
        }
    }
}

AstronomyApiService 클래스 생성.

환경변수는 firebase와 마찬가지로 Dotenv로 파일을 로드하고 가져와주었다.

이후에는 미리 만들어 둔 API에 해당 데이터가 적용이 되어야되니까.

AstronomicalEventControllerObservationLocationController에 적절하게 로직을 수정 및 생성 해주었다.

그래서 이제는 Postman 테스트를 해보자.

이렇게 진행 했고, Json 형식의 값을 받아야하는데

어제처럼 또 로그인 페이지를 반환받았다.

일단 내가 데이터를 잘못 보냈었다. date 값도 함께 보내주니까 이런 결과를 받았다. 보니까 뭐 그런 데이터가 없다는 내용인데 이건 api 설명서를 조금 볼 필요가 있을 것 같다.

가 아니고 로그를 조금 더 세밀하게 볼 수 있게 설정해서 보니까.

API KEY를 제대로 못불러오고 있었던게 원인이였네.

ㅇㅋ 문제 확인 했으니까 고쳐봐야겠지

잘 살펴보니까 .env에서 설정 값과 AstronomyApiService에서 가져오려는 값이 매칭이 제대로 되지 않고 있었다. 찾아서 하니까 이부분에서 더 이상 null은 반환하지 않는다.

하지만

"Invalid key=value pair (missing equal-sign) in Authorization header"

해당 로그가 보였다. 이건 Authorization 헤더에 잘못된 값이 전달되고 있다는 것이다.

HttpHeaderssetBasicAuth() 메서드를 통해 인증 정보를 설정하는 대신, 직접 Authorization 헤더를 추가하는 방식으로 변경해보도록 하자.


을 해도 안된다.

생각해보니까 공홈의 글이 영어로 되어있어서 제대로 읽어본 적이 없는데

여기글을 번역해달라고 GPT한테 요청하고 어떤 방식으로 인증을 받는지 확인해보았다.

AstronomyAPI는 Basic Authentication 방식을 사용해 인증을 처리한다고 하고, applicationIdapplicationSecret을 :로 연결해서 Base64 인코딩을 해야 하고,
Authorization 헤더에 이 인코딩된 값을 넣고, 반드시 "Basic" 키워드를 앞에 붙여야한다고 한다.

아 진작 읽어보고 할걸.

이제 이 방식을 그대로 적용해서 코드를 고쳐보자.

코드는 고쳤고 CORS 헤더 설정도 나중에 필요하다고 한다. Application을 만들 때 Origin 값을 정확하게 설정해야 한다.

그래서 그냥 지금 했다 postman단계에서는 필요없지만 나중에 문제 될 요소는 제거하고 싶어서.

그래서 시큐리티클래스를 조금 더 분리해서 관리하도록 수정했다.

이 과정에서 순환참조 문제가 발생해서,

이것도 해결하고 가자.

예전에 개인 프로젝트때 겪어본적이 있다.

암튼 해결 했고, 이후 다시 포스트맨 요청 해보자.


지금 이제 이거 구현을 하다가 React 프로젝트 통합을 하고와서 글이 좀 끊긴 느낌이 들 것이다.

왜? 딴길로? 샜냐?

Spring으로 처리하려다가 해도해도 안되서 공식 문서에서는 JAVA 코드가 존재하지 않아 그냥 따라가려고 파이썬이나 JS로 처리를 해볼까 라는 생각에 도달해서 JS로 해보다가 문득 리액트랑 타임리프를 같이 사용하는게 맞나? 라는 생각에 도달해서 타임리프 삭제하고 리액트 서버를 통합해서 구글로그인 로직이 정상 실행되고 그린 화면이 백엔드 서버로도 나타나는가를 검증하고 옴..

여튼 이제 다시 우리가 구현하던 것을 하면 된다.

JS로 돌리기로 결정했다.

여기서 보면.

  1. API 인증을 프론트엔드에서 처리하는 경우 (JS에서)
    장점:
  • 속도: 인증 및 API 호출이 클라이언트 측에서 즉시 이루어지기 때문에 응답 속도가 빠를 수 있어.

  • 직접 API 호출: 백엔드와의 중계 없이, 프론트엔드가 직접 API 서버와 통신할 수 있어 상대적으로 간단할 수 있음.

  • 구현의 간결성: 백엔드를 따로 건드리지 않고도 프론트엔드에서 필요한 API 작업을 처리할 수 있어서 구현이 쉬움.
    단점:

  • 보안 문제: 클라이언트 측에서 API Key 또는 민감한 정보를 직접 다루면, API 키가 노출될 위험이 커. 브라우저 개발자 도구를 통해 요청을 볼 수 있기 때문에, 민감한 정보는 쉽게 유출될 수 있음.

  • 사용자 권한 관리 어려움: 백엔드에서 세밀하게 사용자 인증이나 접근 권한을 관리하는 것이 어려울 수 있어. 사용자의 세션을 직접적으로 관리하는 경우에도 보안적으로 취약함.

  • CORS 문제: API 서버와 클라이언트 사이에 CORS 문제가 발생할 수 있음. 특히 프론트에서 외부 API로 직접 요청할 때, CORS 정책을 위반할 수 있어서 이 부분을 해결해야 함.

이런 문제가 있긴한데 어차피 공공데이터인데 보안이 무슨 상관이겠냐 싶어서 프론트로 확실하게 돌리기로 결심했다.
CORS 문제가 조금 어지러울 것 같긴한데, 뭐 지금 손도 제대로 못대고 있는 상황보다야 나을 것 같다.

그건 나중에 이슈가 발생하면 그 때 해결하면 된다.

일단 다시 JS로 연결을 구현해보자,

services 디랙토리에 astromy.js 생성하고 여기서 API 호출, 컨포넌트에 이걸 불러올 버튼을 선언해주고 앱에 라우터로 등록시켰다.

버그 발생!

나한테 왜그래 이제 그만해 ㅠㅠ

빌드에 대한 버그라서 빌드 쪽을 살펴보았다.

문제 해결을 위해서 React에서 npm run build를 실행시키고 로그를 보니까.

not Define이 떠서 보니까 라우터 등록을 시켰는데 임포트를 안했네..

금방 해결.

음 테스트 해봤는데 안된다.

그냥 API측에 조금 문제가 있는 것 같다.

분명히 일치를 하는데 못잡는다. GPT한테 물어보니까 문의 하랜다.

그래서 그냥 버리자.

이건 버리는게 맞다.

그래서 차선책이 뭔데?

Skyfield Python 라이브러리가 있다고 한다.

1. 정밀한 천문 이벤트 계산

Skyfield는 단순한 천문 데이터 조회가 아니라, 실제로 정확한 위치 기반으로 이벤트를 계산할 수 있는 강력한 도구야. 예를 들어, 일식, 월식, 행성의 근접 현상 등을 사용자가 원하는 날짜와 위치에 맞춰 계산할 수 있다. 이런 기능은 천문 관측 프로젝트에서 큰 장점이 될 수 있다.

2. 커스터마이징 가능성

Skyfield는 코드로 천문 현상을 직접 계산하기 때문에, 커스터마이징이 자유롭다. 예를 들어, 특정 이벤트(유성우나 일식)를 계산해서 사용자 맞춤형 데이터를 제공하는 것도 가능하다. 이를 백엔드 서버에서 파이썬으로 처리한 다음, API로 프론트엔드에 데이터를 전달할 수도 있다.

그러니까... 결론은 Skyfield를 사용해서 천문 데이터를 직접 만들겠다가 결론이다.

뭔가 프로젝트가 점점 거대해지는 것 같아서 무섭긴한데, 다음 포스팅에서 바로 적용하면서 포스팅 해야겠다.