오늘의 에러 !!
카카오계정으로 로그인 실패
AuthError(statusCode=401, reason=Misconfigured, response=AuthErrorResponse(error=misconfigured, errorDescription=invalid android_key_hash or ios_bundle_id or web_site_url))

오늘 방금 막 알아낸 버그이다. 버그라기보단 설정 오류문제이다. 이는 지금와서 생각해보면 제대로 카카오톡 환경 설정에 대해 부족한 부분이 있는 것이었지만 이때 당시에는 잘 몰랐다.
분명히 Debug / Release 모드에서 잘 실행되던 카카오톡 로그인이 실제 배포환경에서는 Auth 에러가 나는 것이다.
왜 그런지 잘 몰랐다 .
분명

여기에서 키해시를 잘 설정해주었건만 .....
그래서 구글링을 해보았다.
카카오톡 디버그 / 릴리즈 모드 키 해쉬값
'카카오톡으로 로그인'을 처음에 설정할 때 카카오 디벨로퍼스에 들어가서 클라이언트의 키 해시를 등록해줘야 한다. 기존에는 앱에서 구하는 방식으로 키 해시를 찾아서 등록을 해놨었는데, 알고보니 플레이스토어에서 릴리즈가 되면 로컬 환경에서의 키 해시와 다른 키로 교체가 된다고 한다.
만약 구글 플레이 개발자 콘솔에서 Google play app signing 기능을 활성화시키셨다면 구글 플레이에 앱이 릴리즈되기 전에 개발자의 로컬 개발 환경에서 릴리즈 키스토어의 시그너쳐가 삭제되고 구글 서버에 저장되어 있는 사이닝키의 시그너쳐로 교체됩니다. 그렇기 때문에 이 사이닝키로 생성한 키해시 또한 등록해줘야 합니다.
따라서 이 키 해시를 구글 플레이에서 제공하는 키로 교체해줘야 한다.
즉, playStore에서 앱 사이닝 기능을 사용하고 있다면 기존의 해시키가 이걸로 교체된다는 얘기가 있었다.
그래서 그 해시키로 구해줘야한다는 뜻이였다..


위와 같이
Google Play -> 앱 무결성 -> 앱 서명
에 들어가서 SHA-1 인증서 지문을 복사해야한다.
그리고 SHA-1 인증서 지문을 base64 로 바꾸어야 한다.
base64 변환 값은 터미널에서
echo [인증서 지문] | xxd -r -p | openssl base64
이렇게 하면 쉽게 구할 수 있다.
그럼 왜 base64 변환값을 바꾸어야 하는가 ?
카카오 SDK는 SHA-1 인증서 지문을 Base64로 인코딩한 값을 사용한다. 이것은 Google에서 제공하는 keystore 인증 방식과 같은 표준 보안 방식에 맞추기 위함이기도 한다.
SHA-1은 기본적으로 16진수(Hex) 형태로 출력되지만,
카카오 SDK에서 인증할 때는 Base64 형태로 변환된 값을 사용해야 한다.
예를 들어, SHA-1 인증서 지문이 다음과 같다면:
3A:45:2C:9F:8A:23:BC:ED:71:9D:10:22:11:45:67:89:AB:CD:EF:01
이를 Base64로 변환하면 다음과 같이 바뀝니다:
OkUsgYojvO1xnRAiEUVniqvN7wE=
이 값을 카카오 개발자 콘솔에 등록해야 정상적으로 API를 사용할 수 있다.

저기만 바꿔주면 클라에서 다른 변경을 해주지 않아도 바로 잘 된다!
왜 배포된 버전으로 테스트 해 볼 생각을 못했을까...
정리
✅ SHA-1 인증서 지문을 등록하는 이유
→ 카카오 API에서 앱의 보안을 위해 올바른 서명이 된 앱인지 확인하기 위함
✅ SHA-1을 Base64로 변환하는 이유
→ 카카오 SDK는 SHA-1 값을 Base64로 변환하여 비교하기 때문
✅ Base64 변환 방법
→ 터미널, PowerShell, 온라인 사이트를 이용해 변환 가능
별채부록
adb 사용법에 대해 잠깐 설명하겠다.
설치된 패키지 목록 확인방법
adb shell pm list packages -f
-> 패키지 목록을 보면 package:/data/app/com.sample.hit-1.apk=com.sample.hit 항목이 있다.
패키지 세부 내용중 액티비티 확인방법
adb shell pm dump com.nexon.hit
-> intent={flg=0x10000000 cmp=com.nexon.hit/com.sample.www.MainActivity}
위와 같이 보일 것이다.. !!!

별책부록
✅ Swift (iOS)에서 카카오 로그인 구현
1. 카카오 SDK 설치
📌 CocoaPods 사용
pod 'KakaoSDKCommon'
pod 'KakaoSDKAuth'
pod 'KakaoSDKUser'
설치 후 pod install 실행
2. Info.plist 설정
카카오 로그인을 사용하려면 Info.plist에 스킴을 추가해야 해.
<key>LSApplicationQueriesSchemes</key>
<array>
<string>kakaokom</string>
<string>kakaotalk</string>
</array>
<key>KAKAO_APP_KEY</key>
<string>카카오 네이티브 앱 키</string>
3. AppDelegate.swift 설정
import KakaoSDKCommon
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
KakaoSDK.initSDK(appKey: "카카오 네이티브 앱 키")
return true
}
}
4. 카카오 로그인 구현
import UIKit
import KakaoSDKAuth
import KakaoSDKUser
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let loginButton = UIButton(type: .system)
loginButton.setTitle("카카오 로그인", for: .normal)
loginButton.addTarget(self, action: #selector(kakaoLogin), for: .touchUpInside)
loginButton.frame = CGRect(x: 50, y: 100, width: 200, height: 50)
view.addSubview(loginButton)
}
@objc func kakaoLogin() {
if UserApi.isKakaoTalkLoginAvailable() {
UserApi.shared.loginWithKakaoTalk {(oauthToken, error) in
if let error = error {
print("카카오 로그인 실패: \(error)")
} else {
print("카카오 로그인 성공, 토큰: \(oauthToken?.accessToken ?? "")")
self.getUserInfo()
}
}
} else {
UserApi.shared.loginWithKakaoAccount {(oauthToken, error) in
if let error = error {
print("카카오 계정 로그인 실패: \(error)")
} else {
print("카카오 계정 로그인 성공, 토큰: \(oauthToken?.accessToken ?? "")")
self.getUserInfo()
}
}
}
}
func getUserInfo() {
UserApi.shared.me() {(user, error) in
if let error = error {
print("사용자 정보 가져오기 실패: \(error)")
} else {
print("사용자 정보: \(user?.kakaoAccount?.email ?? "없음")")
}
}
}
}
✅ Java 클라이언트에서 카카오 소셜 로그인 구현
카카오 로그인을 하려면 크게 3단계를 거쳐야 해.
1. 카카오 로그인 URL로 이동 → 사용자 로그인 → 인증 코드 받기
2. 인증 코드로 액세스 토큰 요청하기
3. 액세스 토큰으로 사용자 정보 가져오기
📌 1) 카카오 로그인 URL로 이동
카카오의 OAuth 2.0 로그인 페이지로 이동해서 사용자가 로그인할 수 있도록 해줘야 해.
public class KakaoAuthClient {
private static final String CLIENT_ID = "카카오 REST API 키";
private static final String REDIRECT_URI = "http://localhost:8080/callback"; // 원하는 콜백 URL
private static final String AUTH_URL = "https://kauth.kakao.com/oauth/authorize";
public static void main(String[] args) {
String loginUrl = AUTH_URL + "?client_id=" + CLIENT_ID +
"&redirect_uri=" + REDIRECT_URI + "&response_type=code";
System.out.println("카카오 로그인 URL: " + loginUrl);
}
}
이 코드를 실행하면 콘솔에 카카오 로그인 URL이 출력돼.
해당 URL을 웹 브라우저에서 열면 사용자가 카카오 계정으로 로그인할 수 있어.
📌 2) 인증 코드로 액세스 토큰 요청
사용자가 로그인을 완료하면 REDIRECT_URI에 code(인증 코드)가 포함되어 리디렉션 돼.
이 code를 이용해서 카카오 서버에 액세스 토큰을 요청해야 해.
import java.io.*;
import java.net.*;
import java.util.*;
public class KakaoTokenClient {
private static final String TOKEN_URL = "https://kauth.kakao.com/oauth/token";
private static final String CLIENT_ID = "카카오 REST API 키";
private static final String REDIRECT_URI = "http://localhost:8080/callback";
private static final String CLIENT_SECRET = "카카오 시크릿 키 (선택)"; // 시크릿 키 사용 시
private static final String GRANT_TYPE = "authorization_code";
public static String getAccessToken(String authCode) throws IOException {
URL url = new URL(TOKEN_URL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
String params = "grant_type=" + GRANT_TYPE +
"&client_id=" + CLIENT_ID +
"&redirect_uri=" + REDIRECT_URI +
"&code=" + authCode;
// 시크릿 키 사용 시 추가
if (!CLIENT_SECRET.isEmpty()) {
params += "&client_secret=" + CLIENT_SECRET;
}
OutputStream os = conn.getOutputStream();
os.write(params.getBytes());
os.flush();
os.close();
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
response.append(line);
}
br.close();
return response.toString(); // JSON 형식의 응답 (access_token 포함)
}
public static void main(String[] args) throws IOException {
String authCode = "카카오에서 받은 인증 코드"; // 웹에서 직접 입력해야 함
String tokenResponse = getAccessToken(authCode);
System.out.println("카카오 액세스 토큰 응답: " + tokenResponse);
}
}
이제 authCode를 입력하면 카카오에서 액세스 토큰을 받을 수 있어!
📌 3) 액세스 토큰으로 사용자 정보 가져오기
이제 받은 access_token을 사용해서 카카오 사용자 정보를 가져오자.
import java.io.*;
import java.net.*;
public class KakaoUserInfoClient {
private static final String USER_INFO_URL = "https://kapi.kakao.com/v2/user/me";
public static String getUserInfo(String accessToken) throws IOException {
URL url = new URL(USER_INFO_URL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Authorization", "Bearer " + accessToken);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
response.append(line);
}
br.close();
return response.toString(); // JSON 형식의 응답 (사용자 정보 포함)
}
public static void main(String[] args) throws IOException {
String accessToken = "카카오에서 받은 액세스 토큰"; // 위에서 받은 토큰을 입력
String userInfo = getUserInfo(accessToken);
System.out.println("카카오 사용자 정보: " + userInfo);
}
}
이제 액세스 토큰을 입력하면 **카카오 사용자 정보(JSON)**를 받을 수 있어!
이렇게 별책부록으로 한번 적어봤어 !!!
'개발 > Etc' 카테고리의 다른 글
구글 플레이스토어 테스트 계정 제공하기 (0) | 2024.10.23 |
---|