org.springframework.web.client.HttpClientErrorException: 403 Forbidden
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:63)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:700)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:653)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:613)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:531)
at com.kakao.controller.KakaoController.customAction(KakaoController.java:144)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:529)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:209)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:481)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:673)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:389)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:926)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1791)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
로그인해서 code와 토큰까지 잘받아왔는데… 그뒤에 메시지 나에게전송이나 친구목록 불러와서 전송하려는 단계에서 막혔습니다… 에러해결원인이 뭔지를 모르겟어요 … 따로 권한 풀라는거 다 한것 같은데 아직 권한을 제가 못받아서 서버에서 거절당하는건가요? 뭐를 신청해야 하나요…?
현재는 수신자 발신자 모두 저로 해서 하고있습니다 친구한테 보내는거 말고 나에게 메시지 보내기 하고있습니다. 그래서 동의하고 엑세스 토큰은 java 컨트롤러 이용해서 받아오고있습니다. ㅜㅜ
@Controller @RequestMapping(“/kakao/*”)
public class KakaoController { @RequestMapping(value= “/login”)
public ModelAndView redirectToKakaoLogin() {
System.out.println(“로긴함수실행”);
return new ModelAndView(“redirect:” + “카카오계정{“REST API 키”}&response_type=code&redirect_uri=http://localhost:8080/kakao/callback”);
}
@GetMapping("/callback")
public String kakaoCallback(@RequestParam("code") String code, Model model, HttpServletRequest request) {
System.out.println("코드 받음: " + code);
model.addAttribute("kakaoCode", code);
// 토큰 받아오기
String accessToken = getAccessToken(code);
// 받아온 토큰 출력
System.out.println("Access Token: " + accessToken);
model.addAttribute("accessToken", accessToken);
HttpSession session = request.getSession();
session.setAttribute("accessToken", accessToken);
return "home";
}
public static String getAccessToken(String code) {
System.out.println("토큰함수실행");
String access_token = null;
try {
// API 엔드포인트 URL
String url = "https://kauth.kakao.com/oauth/token";
// 파라미터 설정
String grantType = "authorization_code";
String clientId = {"REST API 키"};
String redirectUri = "http://localhost:8080/kakao/callback";
// 파라미터 문자열 생성
String params = "grant_type=" + grantType +
"&client_id=" + clientId +
"&redirect_uri=" + redirectUri +
"&code=" + code;
// URL 객체 생성
URL obj = new URL(url);
// HttpURLConnection 객체 생성 및 설정
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
con.setDoOutput(true);
// POST 데이터 전송
OutputStream os = con.getOutputStream();
os.write(params.getBytes(StandardCharsets.UTF_8));
os.flush();
os.close();
// 응답 받기
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// 응답 처리
if (responseCode == HttpURLConnection.HTTP_OK) {
// JSON 파싱
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(response.toString());
access_token = jsonNode.get("access_token").asText();
} else {
System.out.println("토큰 요청 실패. 응답 코드: " + responseCode);
}
} catch (Exception e) {
e.printStackTrace();
}
return access_token;
}
@GetMapping("/custom-action")
public String customAction(Model model, HttpSession session) {
String accessToken = (String) session.getAttribute("accessToken");
if (accessToken != null) {
System.out.println("전송");
System.out.println(accessToken);
model.addAttribute("accessToken", accessToken); // 모델에 accessToken 추가
try {
// 카카오톡 메시지를 보내는 API 엔드포인트 URL
String url = "https://kapi.kakao.com/v2/api/talk/memo/default/send";
// 메시지 내용
String message = "안녕하세요, 카카오톡 메시지를 보내는 예제입니다!";
// 카카오톡 API 요청에 필요한 헤더 설정
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + accessToken);
// 카카오톡 메시지 전송을 위한 요청 본문 설정
HttpEntity<String> request = new HttpEntity<String>(message, headers);
// RestTemplate 객체 생성
RestTemplate restTemplate = new RestTemplate();
// POST 요청으로 메시지 전송
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, request, String.class);
if (response.getStatusCode().is2xxSuccessful()) {
// 메시지 전송 성공
System.out.println("카카오톡 메시지가 성공적으로 전송되었습니다!");
} else {
// 메시지 전송 실패
System.out.println("카카오톡 메시지 전송 실패. 상태 코드: " + response.getStatusCodeValue());
}
} catch (HttpClientErrorException e) {
// HttpClientErrorException 발생 시, 에러 메시지 출력
System.out.println("카카오톡 API 호출 오류: " + e.getMessage());
System.out.println("상태 코드: " + e.getStatusCode());
System.out.println("에러 응답 바디: " + e.getResponseBodyAsString());
} catch (Exception e) {
// 그 외 다른 예외 발생 시, 에러 메시지 출력
e.printStackTrace();
}
}
else {
// 세션에 accessToken이 없는 경우 또는 값이 비어있는 경우
System.out.println("토큰이 없습니다.");
}
return "home";
}