Node.js
[07.08] Unity 카카오 로그인 구현 2 - Unity에서 WebView로 구현하기
ljw4104
2021. 7. 8. 18:10
- 사용 에셋 : UniWebView 4 ( https://assetstore.unity.com/packages/tools/network/uniwebview-4-175993?locale=ko-KR )
- 서버 : AWS EC2
- 사용 패키지 : Express, Passport, Passport-kakao, PM2
- UniWebView 에셋은 Node.js의 Response를 json형태로 받을 수 없다.
- 프로토콜 형태로 받아야된다.
서버 코드 수정
app.get("/auth/kakao/callback", (req, res) => {
passport.authenticate("kakao", (err, user) => {
console.log(user);
const json = JSON.stringify(user);
res.send(
`<script>window.location.href='uniwebview://test?user=${json}';</script>`
);
})(req, res);
});
https://docs.uniwebview.com/api/uniwebviewmessage.html
UniWebViewMessage | UniWebView
UniWebViewMessage Summary Represents a message sent from web content back to Unity. Whenever you want to send some information from web view and handle it in Unity script, you can navigate the user with a link started with "uniwebview://". OnMessageReceive
docs.uniwebview.com
- res.send(json의 string형태)는 UniWebView가 받을 수가 없다.
- 새 창을 띠우고 그 새 창의 프로토콜이 http가 아닌 uniwebview의 형태로만 데이터를 주고받을 수 있다.
- test부분은 그냥 아무거나 넣어도 된다.
- user은 클라이언트에서 받을 객체 이름을 넣어야된다.
- href 주소 부분은 반드시 ' ' 로 감싸야한다. 왜냐하면 ${json}은 " "으로 처리되기 때문에 이상한데서 끊킨다.
- script블록을 닫을 때, 세미콜론(;)을 무조건 달아주어야 한다.
클라이언트 코드
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using Newtonsoft.Json;
public class App : MonoBehaviour
{
public Button btnLogin;
public Text txtUserId;
public Text txtNickname;
public Image imgThumb;
public UniWebView webView;
private const string serverURL = <서버 URL>;
// Start is called before the first frame update
void Start()
{
webView.Frame = new Rect(0, 0, Screen.width, Screen.height);
webView.OnMessageReceived += WebView_OnMessageReceived;
this.btnLogin.onClick.AddListener(() =>
{
webView.Load(serverURL);
webView.Show();
});
}
private void WebView_OnMessageReceived(UniWebView webView, UniWebViewMessage message)
{
string msg = message.RawMessage;
string data = message.Args["user"];
Destroy(webView.gameObject);
res_kakao_user profile = JsonConvert.DeserializeObject<res_kakao_user>(data);
this.txtUserId.text = profile.id.ToString();
this.txtNickname.text = profile.nickname;
string image_url = profile.profile_image_url.Insert(4, "://");
Debug.Log(image_url);
StartCoroutine(this.WaitforLoatThumb(image_url, (texture) =>
{
this.imgThumb.sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.zero);
}));
}
private IEnumerator WaitforLoatThumb(string url, Action<Texture2D> callback)
{
UnityWebRequest www = UnityWebRequestTexture.GetTexture(url);
yield return www.SendWebRequest();
Texture myTexture = DownloadHandlerTexture.GetContent(www);
callback((Texture2D)myTexture);
}
}
public class res_kakao_user
{
public int id;
public string nickname;
public string profile_image_url;
}
- 알 수 없는 이유로 message.Args를 받을 때 profile의 url이 잘려서 나온다. ex) http://k.kakao.~~~~ => httpk.kakao 라는 오류가 발생해서 임의로 "://"를 넣어주었다.
- 이미지는 바로 들어오는 것이 아니라 다 받아와야 들어오기 때문에 Coroutine을 돌려 받아준다.
서버 전체 코드
const express = require("express");
const app = express();
const passport = require("passport");
const KakaoStrategy = require("passport-kakao").Strategy;
let user = {};
passport.use(
new KakaoStrategy(
{
clientID: CLIENT_ID,
clientSecret: CLLIENT_SECRET, // clientSecret을 사용하지 않는다면 넘기지 말거나 빈 스트링을 넘길 것
callbackURL:"CALLBACK_URL",
},
(accessToken, refreshToken, profile, done) => {
let raw = JSON.parse(profile["_raw"]); //문자열을 객체로 parsing
user.id = raw.id;
user.nickname = raw.kakao_account.profile.nickname;
user.profile_image_url = raw.kakao_account.profile.profile_image_url;
done(null, user);
}
)
);
app.get("/auth/kakao", passport.authenticate("kakao", null), (req, res) => {
console.log("failed");
});
app.get("/auth/kakao/callback", (req, res) => {
passport.authenticate("kakao", (err, user) => {
console.log(user);
const json = JSON.stringify(user);
res.send(
`<script>window.location.href='uniwebview://test?user=${json}';</script>`
);
})(req, res);
});
app.listen(3000, () => {
console.log("server is running at 3030 port.");
});