401 Unauthorized 에러 어떻게 해결하나요?

문의 시, 사용하시는 SDK 버전 정보와 디벨로퍼스 앱ID를 알려주세요.


톰캣 사용하는데 자꾸 이렇게 에러가 뜨는데
앱키도 다 변경해보고 했는데 뭐가 문제일까요

작업 내용입니다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>다니엘성형외과의원 진료과목 피부과</title>
<link rel="shortcut icon" href="${pageContext.request.contextPath}/resources/img/favicon.ico">
<!-- ************************************************************************************************* -->
<!-- @ = 스타일, # = 자바스크립트 -->
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/resources/css/style.reset.css"><!-- @1 스타일 초기화		**삭제/수정금지** -->
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/resources/css/style.common.css"><!-- @2 공통 스타일		**삭제금지** -->
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/resources/js/wow/animate.css"><!-- @5 플러그인 Animate CSS -->
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.1/css/all.css" integrity="sha384-5sAR7xN1Nv6T6+dT2mhtzEpVJvfS3NScPQTrOxhwjIuvcA67KV2R5Jz6kr4abQsz" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/resources/css/style.layout.css"><!-- @6 공통 레이아웃(header, footer, snb, visual, sub, inner)	**삭제금지** -->
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/resources/css/style.sub.css"><!-- @ 메인페이지 스타일-->
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/resources/css/style.board.css">
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/resources/css/style.icon.css">
<!-- ********************************************플러그인********************************************* -->
<script src="${pageContext.request.contextPath}/resources/js/jquery-1.12.4.min.js"></script><!-- #1 1.12.4  -->
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/jquery-ui-1.11.1.js"></script><!-- #jquery UI  -->
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/fontawesome/js/fontawesome-all.min.js"></script><!-- #2 플러그인 fontawesome -->
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/slick/slick.js"></script><!-- #3 플러그인 Slick -->
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/wow/wow.min.js"></script><!-- #4 플러그인 Wow -->
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/wow/scrollspy.js"></script><!-- #5 플러그인 Scrollspy -->
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/jquery.rwdImageMaps.js"></script><!-- #6 플러그인 rwdImageMaps -->
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/jquery.sns.share.js"></script><!-- #7 플러그인 SNS SHARE -->
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/jquery.modernizr.js"></script><!-- #8 플러그인 modernizr -->
<!-- ************************************************************************************************* -->
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/jquery.sub.js"></script><!-- # 메인페이지 함수 -->
<!-- ************************************************************************************************* -->
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/function.admin.js"></script><!-- # 필수 함수 -->
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/function.calendar.js"></script><!-- # 필수 함수 -->
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/function.date.js"></script><!-- # 필수 함수 -->
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/function.default.js"></script><!-- # 필수 함수 -->
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/function.user.js"></script><!-- # 필수 함수 -->
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/function.validate.js"></script><!-- # 필수 함수 -->
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/function.default.js"></script><!-- # 필수 함수 -->
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/function.layer.js"></script><!-- # 필수 함수 -->
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/jquery.common.js"></script><!-- # 공통 함수 -->
<!-- <script type="text/javascript" src="https://static.nid.naver.com/js/naverLogin_implicit-1.0.3.js" charset="utf-8"></script> -->
<script type="text/javascript" src="https://static.nid.naver.com/js/naveridlogin_js_sdk_2.0.2.js" charset="utf-8"></script>
<script src="https://t1.kakaocdn.net/kakao_js_sdk/2.1.0/kakao.min.js"
	integrity="sha384-dpu02ieKC6NUeKFoGMOKz6102CLEWi9+5RQjWSV0ikYSFFd8M3Wp2reIcquJOemx" crossorigin="anonymous"></script>
<style>
.snsLoginBtn{
	width: 100%;
	text-align: center;
	padding-top: 20px;
}
</style>
<script>
function userIdPwChk(info){
	$.ajax({
		url:"${pageContext.request.contextPath}/loginIdPwChk",
		type:"POST",
		contentType : "application/json; charset=UTF-8",
		dataType:"text",
		data: JSON.stringify(info),
		async:false,
		success:function(json){
			if(json == "empty" || json =="no"){
				alert("일치하는 정보가 없습니다.");
				
			}else if(json == "ok"){
				var prev_url = document.referrer;
	            var target_url = "n";
	            if(prev_url.indexOf("menu09_03") >= 0){
	            	target_url = "menu09_03";
	            }
	            if(prev_url.indexOf("menu09_05") >= 0){
	            	target_url = "menu09_05";
	            }
	            if(target_url == "menu09_03"){
	            	location.href="${pageContext.request.contextPath}/menu09_03";
	            }else if(target_url == "menu09_05"){
	            	location.href="${pageContext.request.contextPath}/menu09_05";
	            }else{
	            	location.href="${pageContext.request.contextPath}/";
	            }
				
			}
		},
		error:function(request,status,error){
			console.log("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
		}
	});
}

$(function(){
	$("#loginBtn").click(function(){
		var id = $("#m_id").val();
		var pw = $("#m_pass").val();
		var info = {"id":id, "pw":pw};
		
		userIdPwChk(info);
	});
});
</script>
</head>
<body>
	<!-- 페이지 로딩 시작 -->
	<div id="loader-wrapper">
		<div id="loading"></div>
	</div>
	<!-- 페이지 로딩 끝 -->
	
	<!-- SkipNavigation 시작 -->
	<div id="skipnavigation">
		<ul>
			<li><a href="#sub-container">본문 바로가기 <svg class="svg-inline--fa fa-arrow-circle-right fa-w-16" aria-hidden="true" data-fa-processed="" data-prefix="fas" data-icon="arrow-circle-right" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M256 8c137 0 248 111 248 248S393 504 256 504 8 393 8 256 119 8 256 8zm-28.9 143.6l75.5 72.4H120c-13.3 0-24 10.7-24 24v16c0 13.3 10.7 24 24 24h182.6l-75.5 72.4c-9.7 9.3-9.9 24.8-.4 34.3l11 10.9c9.4 9.4 24.6 9.4 33.9 0L404.3 273c9.4-9.4 9.4-24.6 0-33.9L271.6 106.3c-9.4-9.4-24.6-9.4-33.9 0l-11 10.9c-9.5 9.6-9.3 25.1.4 34.4z"></path></svg><!-- <i class="fas fa-arrow-circle-right"></i> --></a></li>
		</ul>
	</div>
	<!-- SkipNavigation 끝 -->	
	
	<div id="wrap">
		<!-- 해더 시작  -->
		<jsp:include page="../include/pcHeader.jsp"></jsp:include>
		<!-- 해더 끝  -->
		
		<!-- 콘텐츠 영역 시작 (메인일 경우 #main-container / 서브일 경우 #sub-container) -->
		<section id="sub-container">
			<!--  닫기 [위치 : include_web_footer.html ]  -->

			<!-- 서브 비주얼영역 시작  -->
			<div id="sub-visual" data-menu="로그인">
				<div class="sub-visual-tit">
				
				</div>
			</div>
			<!-- 서브 비주얼영역 끝 -->
			
			<!-- BreadCrumb 시작 -->
			<%-- <div id="breadcrumb">
				<div class="inner">
					<ul>
						<li class="home">
							<a href="${pageContext.request.contextPath}/" title="메인페이지로 이동"></a>
						</li>
						<li class="gnb">
							<button>멤버쉽 ▼</button>
							<ul>
								<jsp:include page="../include/pcBreadCrumb.jsp"></jsp:include>				
							</ul>
						</li>
						<li class="gnb">
							<button>로그인 ▼</button>
						</li>
					</ul>
				</div>
			</div> --%>
			<!-- BreadCrumb 끝 -->
			
			<!-- 타이틀 시작 -->
			<div class="board-titl">
				<h5>로그인</h5>
			</div>
			<!-- 타이틀 끝 -->
			
			
			<!-- 로그인 폼 시작 -->
			<div id="login-form">
				<ul class="login-inner">
					<li class="login">
						<form name="member" id="member" method="post" action="" onsubmit="">
							<input type="hidden" name="mode" value="login">
							<input type="hidden" name="distinction" value="proc">
							<input type="hidden" name="url" value="">
							<input type="hidden" name="backpage" value="/login">
							<p>
								<label for="m_id">아이디</label>
								<input id="m_id" name="m_id" type="text" valid="required" element-name="아이디" placeholder="아이디를 입력하세요">
							</p>
							<p>
								<label for="m_pass">비밀번호</label>
								<input id="m_pass" name="m_pass" type="password" valid="required" element-name="비밀번호" placeholder="비밀번호를 입력하세요">
							</p>
							<button type="button" id="loginBtn">로그인</button>
							<div class="snsLoginBtn">
								<span id="naverIdLogin"></span>
								<a id="kakao-login-btn" href="javascript:loginWithKakao()">
									<img src="/resources/img/contents/kakao_login_button.png" height="50" alt="카카오 로그인 버튼" />
								</a>
							</div>
						</form>
						<script type='text/javascript'>
						
							// 사용할 앱의 JavaScript 키를 설정해 주세요.
							Kakao.init('2ea6fa0bfd2f64b5998667415444ff58');
						
							function loginWithKakao() {
								
								let serverName = '${pageContext.request.serverName}';
								let redirectUrl;
								
								if (serverName === 'localhost') {
									let serverPort = '${pageContext.request.serverPort}';
									redirectUrl = 'http://' + serverName + ":" + serverPort + '/kakao/login/oauth';
								} else {
									redirectUrl = 'http://' + serverName + '/kakao/login/oauth';
								}
								
								var prevUrl = document.referrer;
								
						    	Kakao.Auth.authorize({
									redirectUri: redirectUrl,
									state: prevUrl,
								});

							}
							
							function snsKakaoLogin() {
								Kakao.API.request({
								  url: '/v2/user/me',
								})
									.then(function(res) {
							            var user = res.id;
							            var prevUrl = '${targetPage}';
							            var targetUrl = "n";
							            if(prevUrl.indexOf("menu09_03") >= 0){
							            	targetUrl = "menu09_03";
							            }
							            if(prevUrl.indexOf("menu09_04") >= 0){
							            	targetUrl = "menu09_04";
							            }
							            if(prevUrl.indexOf("menu09_05") >= 0){
							            	targetUrl = "menu09_05";
							            }
							            location.href = "/snsLogin/" + user + "?targeturl=" + targetUrl;
									})
									.catch(function(err) {
										alert('알 수 없는 이유로 카카오 로그인에 실패하셨습니다.\n다시 시도해주시거나 다른 로그인 방식을 시도해주세요.');
										console.log(JSON.stringify(error));
									});
							}
							
							// 아래는 데모를 위한 UI 코드입니다.
							checkKakaoLogin();
							
							function checkKakaoLogin() {
							  var token = getCookie('kakao-authorize-access-token');
							  
							  if (token) {
							    Kakao.Auth.setAccessToken(token);
							    snsKakaoLogin();
							  }
							}
							
							function getCookie(name) {
							  var parts = document.cookie.split(name + '=');
							  if (parts.length === 2) { return parts[1].split(';')[0]; }
							}
						</script>
						<script type="text/javascript">
						
							function getNaverLoginClientId() {
								let serverName = '${pageContext.request.serverName}';
								
								if (serverName === 'localhost') {
									return "C8WjwdaGYwlrqpdcXfre";
								} else {
									return "l3z4vVcQoOnP5sPbj5WR";
								}
							}
						
							function getNaverLoginRedirectUrl() {
								
				            	let serverName = '${pageContext.request.serverName}';
								let redirectUrl;
								
								if (serverName === 'localhost') {
									let serverPort = '${pageContext.request.serverPort}';
									redirectUrl = 'http://' + serverName + ":" + serverPort + '/naver/login/oauth';
								} else {
									redirectUrl = 'http://' + serverName + '/naver/login/oauth';
								}
								
								var prev_url = document.referrer;
					            var target_page = "n";
					            if(prev_url.indexOf("menu09_03") >= 0){
					            	target_page = "menu09_03";
					            }
					            if(prev_url.indexOf("menu09_04") >= 0){
					            	target_page = "menu09_03";
					            }
					            if(prev_url.indexOf("menu09_05") >= 0){
					            	target_page = "menu09_05";
					            }
								
								return redirectUrl + '?target_page=' + target_page;
				            }
				        	
				        	var naverLogin = new naver.LoginWithNaverId(
								{
									clientId: getNaverLoginClientId(),
									callbackUrl: getNaverLoginRedirectUrl(),
									isPopup: false, /* 팝업을 통한 연동처리 여부 */
									loginButton: {color: "green", type: 3, height: 49}, /* 로그인 버튼의 타입을 지정 */
								}
							);
							
							/* 설정정보를 초기화하고 연동을 준비 */
							naverLogin.init();
							
						</script>
						
					</li>
					<li class="member">
						<p>
							아이디나 비밀번호를 분실하셨나요?<a href="${pageContext.request.contextPath}/findId">아이디/비밀번호 찾기</a>
						</p>
						<p>
							아직 회원이 아니신가요?<a href="${pageContext.request.contextPath}/join" class="btn-join">회원가입</a>
						</p>
					</li>
				</ul>
			</div>
			<!-- 로그인 폼 끝 -->
			
		</section> <!-- #main-container , #sub-container 닫기 [위치 : include_web_top.html ] -->
	
	
		<!-- 메인페이지 오시는길(오시는길, 진료시간 안내, 상담문의) 시작 -->
		<jsp:include page="../include/pcBottom.jsp"></jsp:include>
		<!-- 메인페이지 오시는길(오시는길, 진료시간 안내, 상담문의) 끝 -->
	
		<!-- 풋터 시작 (style.layout.css) -->
		<jsp:include page="../include/pcFooter.jsp"></jsp:include>
		<!-- 풋터 끝 (style.layout.css) -->
		
		<!-- 서브페이지 우측 퀵배너 시작 -->
		<jsp:include page="../include/pcQuick.jsp"></jsp:include>
		<!-- 서브페이지 우측 퀵배너 끝 -->

	</div><!-- #wrap end -->
	
	<!-- 빠른상담 신청하기 폼 시작 -->
	<jsp:include page="../include/pcQuickInquire.jsp"></jsp:include>
	<!-- 빠른상담 신청하기 폼 끝 -->
	
	<!-- 개인정보 취급방침 팝업 시작 -->
	<jsp:include page="../include/pcPopPrivate.jsp"></jsp:include>
	<!-- 개인정보 취급방침 팝업 끝 -->
</body>
</html>

안녕하세요.

KakaoLoginController.java 에서 API 사용 시, 401 오류 발생하였습니다.
해당 소스 코드 제공 부탁드립니다.

package com.webaid.controller;

import com.webaid.domain.KakaoTokenInfo;
import java.nio.charset.Charset;
import java.util.Collections;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.mobile.device.Device;
import org.springframework.mobile.device.DeviceUtils;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

@Controller
@RequestMapping({"/kakao/login"})
public class KakaoLoginController {
  @GetMapping({"/oauth"})
  public String kakaoLoginProcess(@RequestParam String code, @RequestParam(name = "state", required = false) String targetPage, HttpServletRequest request, HttpServletResponse response, RedirectAttributes ra) {
    String result, redirectUrl = request.getRequestURL().toString();
    String url = "https://kauth.kakao.com/oauth/token";
    UriComponents uri = UriComponentsBuilder.fromHttpUrl(url).build(false);
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
    headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
    LinkedMultiValueMap linkedMultiValueMap = 
      new LinkedMultiValueMap();
    linkedMultiValueMap.add("grant_type", "authorization_code");
    linkedMultiValueMap.add("client_id", "3bd6f4a3936708269ffa0be876126143");
    linkedMultiValueMap.add("redirect_uri", redirectUrl);
    linkedMultiValueMap.add("code", code);
    HttpEntity<MultiValueMap<String, String>> requestEntity = 
      new HttpEntity(linkedMultiValueMap, (MultiValueMap)headers);
    RestTemplate restTemplate = new RestTemplate();
    restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
    KakaoTokenInfo kakaoTokenInfo = (KakaoTokenInfo)restTemplate.postForObject(uri.toUri(), requestEntity, KakaoTokenInfo.class);
    Device device = DeviceUtils.getCurrentDevice(request);
    String deviceType = "unknown";
    Cookie cookie = new Cookie("kakao-authorize-access-token", kakaoTokenInfo.getAccess_token());
    cookie.setMaxAge(kakaoTokenInfo.getExpires_in().intValue());
    if (device == null) {
      deviceType = "unknown";
      cookie.setPath("/login");
      result = "redirect:/login";
    } else if (device.isMobile()) {
      deviceType = "mobile";
      cookie.setPath("/m/login");
      result = "redirect:/m/login";
    } else if (device.isTablet()) {
      deviceType = "mobile";
      cookie.setPath("/m/login");
      result = "redirect:/m/login";
    } else {
      deviceType = "normal";
      cookie.setPath("/login");
      result = "redirect:/login";
    } 
    response.addCookie(cookie);
    ra.addFlashAttribute("targetPage", targetPage);
    return result;
  }
}

소스코드에 사용하신 앱 키는 삭제된 앱의 키 입니다.
유효한 앱 키 사용 부탁드립니다.

image

이거 네개 다 써봤는데 오류 떠요ㅜㅜ
혹시 바꾸고 저장하고 새로고침하고 좀 기다려야하나요?
[/quote]

에러 응답 메시지 기재 부탁드려요.

http://www.danielps.co.kr/kakao/login/oauth?code=yaLGxMhYBFXlQ7N3xBzKwOvFghREUkmSGamvI_cIaCqoVAkmbcwrFjt2CPkKPXTZAAABi_YMN3NSGUcvaFb1Eg&state=http%3A%2F%2Fwww.danielps.co.kr%2F

이렇게 뜨네요ㅜ ㅜ

에러 Response Body에 상세 에러 메시지 확인 부탁드려요.

[rest api 예제] java (spring boot) - 카카오 로그인, 카카오 친구목록 조회, 나에게 메시지 발송

			InputStream stream = conn.getErrorStream();
		    if (stream != null) {
			    try (Scanner scanner = new Scanner(stream)) {
			        scanner.useDelimiter("\\Z");
			        response = scanner.next();
			    }			
			    System.out.println("error response : " + response);
		    }