유니티 연동 카카오 로그인

2021. 7. 8. 18:13Node.js

 

https://www.npmjs.com/package/passport-kakao

 

passport-kakao

kakao oauth2 login module

www.npmjs.com

npm init -y
npm i express
npm i express supervisor
npm i passport
npm i passport-kakao

const express = require("express");
const app = express();
const passport = require("passport");
const kakaoStrategy = require("passport-kakao").Strategy;

let user = {};

passport.use(
    new kakaoStrategy(
        {
            clientID: "b10873b9ba0a68445daf5f2cfa6ce00d",
            clientSecret: "",
            callbackURL: "http://localhost:3030/auth/kakao/callback",
        },
        (accessToken, refreshToken, profile, done) => {
            // 사용자의 정보는 profile에 들어있다.
            let raw = JSON.parse(profile["_raw"]);

            user.nickname = raw.kakao_account.profile.nickname;
            user.profile_image_url = raw.kakao_account.profile.profile_image_url;
            user.id = profile.id;
            done(null, user);
        }
    )
);

app.get('/', (req, res) => {
    res.send("Hello World");
});

app.listen(3030, () => {
    console.log('server is running at port 3030...');
});

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);
        let json = JSON.stringify(user);
        res.send(json);
    })(req, res);
}

);

 

로컬호스트:3030/auth/kakao로 들어가 해당 항목을 체크 후 로그인하면 콜백 주소로 가
닉네임, id, 이미지 url이 출력된다.
이미지 url로 들어가면 현재 내 카카오 프사가 뜸.

 


이제 유니티 웹뷰를 이용해서 카카오 로그인을 구현

UniWebView4를 임포트하고 
간단한 ui 구성
UniWebView는 안드로이드 21이상부터만 지원되기에 프로젝트 세팅에서 번경

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using Newtonsoft.Json;


public class res_kakao_user 
{
    public int id;
    public string nickname;
    public string profile_image_url;
}

public class App : MonoBehaviour
{
    public Button btnLogin;
    public UniWebView webView;
    public Text txtUserId;
    public Text txtNickName;
    public Image imgProfile;


    // Start is called before the first frame update
    void Start()
    {
        this.btnLogin.onClick.AddListener(() => 
        {
            webView.Frame = new Rect(0, 0, Screen.width, Screen.height);
            webView.OnMessageReceived += WebView_OnMessageReceived;
            webView.Load("http://ec2-3-35-205-27.ap-northeast-2.compute.amazonaws.com:3000/auth/kakao");

            webView.Show();
        });
    }

    private void WebView_OnMessageReceived(UniWebView webView,UniWebViewMessage message )
    {
        Debug.Log(message.RawMessage);
        
        Destroy(webView.gameObject);

        var user = JsonConvert.DeserializeObject<res_kakao_user>(message.RawMessage);
        this.txtUserId.text = user.id.ToString();
        this.txtNickName.text = user.nickname.ToString();

        StartCoroutine(this.WaitForLadThumb(user.profile_image_url, (texture) =>
        {
            this.imgProfile.sprite = Sprite.Create(texture, new Rect(0,0,texture.width,texture.height),Vector2.zero);
        }));
    }

    private IEnumerator WaitForLadThumb(string url, System.Action<Texture2D> callback) 
    {
    //https://docs.unity3d.com/Manual/UnityWebRequest-RetrievingTexture.html
        UnityWebRequest www = UnityWebRequestTexture.GetTexture(url);
        yield return www.SendWebRequest();

        Texture myTexture = DownloadHandlerTexture.GetContent(www);
        callback((Texture2D)myTexture);
    }
}

apk로 빌드해서 로그인을 해보니 위 함수에서 Destroy()한 것이 먹히질 않는다.

UniwebView는 JSON 파일을 직접 읽어올 수 없기에 프로토콜이 필요하다.
그래서 UniWebView에서 따로 만들어둔 프로토콜이 있는데,
'uniwebview://action?쿼리'로 만들어진 새로 만들어진 창이 유니티와 통신하는데 쓰임.
쿼리로 json이 들어오는데, json자체에 이미 " "가 있으므로 앞의 콤마를 ' '로 바꿔주었다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using Newtonsoft.Json;


public class res_kakao_user 
{
    public int id;
    public string nickname;
    public string profile_image_url;
}

public class App : MonoBehaviour
{
    public Button btnLogin;
    public UniWebView webView;
    public Text txtUserId;
    public Text txtNickName;
    public Image imgProfile;


    // Start is called before the first frame update
    void Start()
    {
        this.btnLogin.onClick.AddListener(() => 
        {
            webView.Frame = new Rect(0, 0, Screen.width, Screen.height);
            webView.OnMessageReceived += WebView_OnMessageReceived;
            webView.Load("http://ec2-3-35-205-27.ap-northeast-2.compute.amazonaws.com:3000/auth/kakao");

            webView.Show();
        });
    }

    private void WebView_OnMessageReceived(UniWebView webView,UniWebViewMessage message )
    {
        Debug.Log(message.RawMessage);
        
        Destroy(webView.gameObject);

        var user = JsonConvert.DeserializeObject<res_kakao_user>(message.Args["user"]);
        this.txtUserId.text = user.id.ToString();
        this.txtNickName.text = user.nickname.ToString();

        var imgUrl = user.profile_image_url.Insert(4, "://");
        Debug.Log(imgUrl);
        //url이 'http://'이 떨어져서 들어오기에 따로 붙혀주었다.

        StartCoroutine(this.WaitForLadThumb(imgUrl, (texture) =>
        {
            this.imgProfile.sprite = Sprite.Create(texture, new Rect(0,0,texture.width,texture.height),Vector2.zero);
        }));
    }

    private IEnumerator WaitForLadThumb(string url, System.Action<Texture2D> callback) 
    {
        UnityWebRequest www = UnityWebRequestTexture.GetTexture(url);
        yield return www.SendWebRequest();

        Texture myTexture = DownloadHandlerTexture.GetContent(www);
        callback((Texture2D)myTexture);
    }
}
const express = require("express");
const app = express();
const passport = require("passport");
const kakaoStrategy = require("passport-kakao").Strategy;

let user = {};

passport.use(
    new kakaoStrategy(
        {
            clientID: "b10873b9ba0a68445daf5f2cfa6ce00d",
            clientSecret: "",
            callbackURL: "http://localhost:3030/auth/kakao/callback",
        },
        (accessToken, refreshToken, profile, done) => {
            // 사용자의 정보는 profile에 들어있다.
            let raw = JSON.parse(profile["_raw"]);

            user.nickname = raw.kakao_account.profile.nickname;
            user.profile_image_url = raw.kakao_account.profile.profile_image_url;
            user.id = profile.id;
            done(null, user);
        }
    )
);

app.get('/', (req, res) => {
    res.send("Hello World");
});

app.listen(3030, () => {
    console.log('server is running at port 3030...');
});

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);
        let json = JSON.stringify(user);
        res.send(
            `<script>window.location.href = 'uniwebview://test?user=${json}';</script>`
        );
    })(req, res);
}

);

로그인 제대로 됨.

 

'Node.js' 카테고리의 다른 글

DB 생성하기 복습+procedure+view+transcation+function+trigger  (0) 2021.07.13
express 서버 열어서 POST/GET  (0) 2021.07.12
0708 구글 애널리틱스  (0) 2021.07.08
0630 firebase + google analytics  (0) 2021.06.30
Naver login  (0) 2021.06.24