[flutter] - social login : Kakao login
이번에 개발을 하면서 social login이 필요해졌다. 공부하며 정리차원에 글을 써본다. (삽질을 많이했다…)
먼저 Kakao Login으로 진행해보겠다.
준비
Plugin
kakao_flutter_sdk
이라는 외부 라이브러리를 사용할 예정이다. (kakao 공식라이브러리니 안심하고 쓰자.)Kakao API Key
Kakao Develpoers
에 접속하여 앱을 등록하고 key를 발급받는다.
1. 프로젝트 생성
일단 테스트앱으로 진행해보겠다.
vscode
에서 새로운 프로젝트를 생성하고 pubspec.yaml
에 플러그인을 등록한다.
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^0.1.2
kakao_flutter_sdk: ^0.4.2
...
자 기본 준비는 끝났다.
2. 화면 만들기
테스트 앱이여도 화면이 필요하니 빠르게 구성해보자
3. 로그인 기능 작성
먼저 kakao Develpoers
에서 발급 받은 API key
를 입력하자
void main() {
KakaoContext.clientId = '나의 네이티브 아이디';
runApp(MyApp());
}
카카오톡에는
2가지 로그인 분기
가 존재한다.- 웹을 통한 로그인
- 카카오톡을 통한 로그인
2번째 카카오톡을 통한 로그인은
카카오톡이 설치
되어 있어야한다.
- 먼저 카카오톡이 설치되어있는지 확인하는 코드를 넣어보자.
bool _isKakaoTalkInstalled = true;
@override
void initState() {
super.initState();
_initKakaoTalkInstalled();
}
_initKakaoTalkInstalled() async {
final installed = await isKakaoTalkInstalled();
setState(() {
_isKakaoTalkInstalled = installed;
});
}
- 그리고 먼저
웹을 통한 로그인
_loginWithKakao() async {
try {
var code = await AuthCodeClient.instance.request();
await _issueAccessToken(code);
} catch (e) {
print(e);
}
}
카카오톡을 통한 로그인
_loginWithTalk() async {
try {
var code = await AuthCodeClient.instance.requestWithTalk();
await _issueAccessToken(code);
} catch (e) {
print(e);
}
}
- 로그인 분기에서
token
을 받아오는 함수이다._issueAccessToken(String authCode) async { try { var token = await AuthApi.instance.issueAccessToken(authCode); AccessTokenStore.instance.toStore(token); Navigator.push( context, MaterialPageRoute(builder: (context) => Login()), ); } catch (e) { print("error on issuing access token: $e"); } }
로그인 성공시 (
token
받아올 시)Login
화면으로 이동한다.
여기까지하면 코드는 완성이다. 하지만 이제 시작이다.
4. 카카오톡 로그인 설정
나는 여기서 많이 방황했다… ㅠ
먼저 kakao_flutter_sdk
의 example
코드를 보고 따라했다.
AnroidManifest.xml
아래 코드를 꼭 넣어주자
<uses-permission android:name="android.permission.INTERNET" />
<activity android:name="com.kakao.sdk.flutter.AuthCodeCustomTabsActivity">
<intent-filter android:label="flutter_web_auth">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="kakao나의 API KEY" android:host="oauth"/>
</intent-filter>
</activity>
kakao나의 API KEY
에서는 단순히 키만 적는게 아니라 꼭 앞에kakao
를 붙여줘야한다.
그리고 또 중요한 hash key
를 받으러 가보자
5. Android hash Key 등록
하면서 알게된거지만 터미널
에서 keytool
로 hash key
를 가져오면 안되는 경우가 많다. (나는 계속 안됬다…) 가장 확실한건 native code
에서 가져오는거다.
다음은 kotlin
기준으로 작성하겠다. 먼저 android/app/src/main/kotlin
아래 있는 MainActivity.kt
파일을 연다.
그리고 아래와 같이 작성한다.
class MainActivity: FlutterActivity() {
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
}
@Override
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
try {
val info: PackageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES)
for (signature in info.signatures) {
var md: MessageDigest
md = MessageDigest.getInstance("SHA")
md.update(signature.toByteArray())
val something = String(Base64.encode(md.digest(), 0))
Log.d("hash", something.toString())
}
} catch(e: Exception) {
Log.e("name not found", e.toString())
}
}
}
android studio
에서 진행하는걸 추천하며vscode
에plugin
이 없을 시import
를 직접해줘야한다. 그리고 꼭import io.flutter.Log
를 넣어주자
이렇게 작성하고 android studio
로 실행해서 logcat
을 확인하자.
자 이렇게 뽑아온 hash key
를 kakao developer
사이트에 등록해주자
6. IOS 설정
IOS 13.3.1
에서 문제가 있어flutter
build
가 안된다…. 글을 찾아보니13.4 beta
에서는 정상작동한다며 기다리라고 한다….가상머신
으로IOS12
에서 돌려보자
먼저 xcode
에서 Runner/Info
에서 URL Types
에 다음 이미지처럼 API KEY
를 추가하자
API KEY
에kakao
를 앞에 붙여야한다.
추가적으로 Info.plist
에서도 KAKAO_APP_KEY
를 key
로 String
값에 API KEY
를 추가하자
Kakao Developer
에 IOS
를 추가한다
Build
하거나pod install
할때 분명 에러가 뜰것이다… 왜냐하면kakao_sdk
는IOS11
이상만 지원하기 때문이다. 해결법은Podfile
에 들어가서 상단의 주석을 지우고IOS11
으로 수정한다.
# Uncomment this line to define a global platform for your project
platform :ios, '11.0'
7. 결과화면
자 이렇게 설정하면 로그인 버튼
을 클릭하면 다음 화면이 뜬다. (카카오톡이 있다면 동의를 구하고 스킵된다.)
로그인 성공시 내가 설정한 화면이다. (nickname
출력)
_getUserId() async {
User user = await UserApi.instance.me();
setState(() {
id = user.kakaoAccount.profile.toJson()['nickname'].toString();
});
}