Unity/서버

0708_ 카카오로그인 ( 유니티에서 WebView_OnMessageReceived 데이터 받아서 유니티에서 띄우기)

minquu 2021. 7. 8. 12:50
반응형

새로운 프로젝트 만들기

 

안드로이드로 빌드 - 검은 화면에 카카오 버튼을 누르면 로그인이 뜨게하기

 

 

 

 

 

z

 

카카오 개발자 센터 앱 만들고

웹플랫폼 

 

 

리 다이렉트 URI 등록해주기

 

활성화하기

 

 

 

 

 

 

동의항목에서 필요한것들 설정하기

 

 

npm에서 카카오 패스폴트 검색

 

 

비코에서 폴더만들기

 

 

만든 폴더로 들어오기

 

 

npm init -y // 초기화 해주기

 

app.js 만들기

 

노드몬도 깔고

 

 

 

 

 

기본 express 서버를 만들어준다.

 

카카오 패스폴트 깔기

 

그냥 패스폴트도 깔고 

 

 

 

 

클라 아이디는 

 

 

rest api 키 넣기

 

보안 키 있으면 

여기서 만들어서 넣기

 

 

콜백 URL

 

 

 

 

아까 만든 URL 넣기 

 

그냥 아래 코드 app.js 넣고 실행...

 

----

app.js

 

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

let user = {};

passport.use(
    new KakaoStrategy(
        {
            clientID: "6c286dd40f3166ecc7f6dce7ba9469e5",
            clientSecret: "bdvz3V5sKf47U9Sw8M7YYcGzUeeGGkBm", // clientSecret을 사용하지 않는다면 넘기지 말거나 빈 스트링을 넘길 것
            callbackURL: "http://localhost:3030/auth/kakao/callback",
        },
        (accessToken, refreshToken, profile, done) => {
            // 사용자의 정보는 profile에 들어있다.
            console.log(profile.id);
            user.id = profile.id;
            done(null, user);
        }
    )
);

app.get("/auth/kakao", passport.authenticate("kakao", null), (req, res) => {
    console.log("failed");
});

app.get(
    "/auth/kakao/callback",
    passport.authenticate("kakao", (err, user) => {
        // console.log(err);
        console.log("come ")
        console.log(user);
    })
);

app.get("/", (req, res) => {
    res.send("<h1>hello express!!</h1>");
});

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

 

여기 라우터로 들어가면 로그인을 할 수있고,

 

로그인 후 

 

http://localhost:3030/auth/kakao/callback

 

이 라우터로 이동한다.

 

 

그래서 /auth/kakao 로 들어가면

 

/auth/kakao/callback  으로 들어간다.

 

스크린샷에서 'come' 이 찍히는걸 확인할 수잇다 .

 

----

 

 

 

 

 

 

http://localhost:3030/auth/kakao 로들어가면 

 

console.log(profile["_raw"]);

 

를 넣은 _raw 가 json 형식으로 나온다.

 

http://jsonviewer.stack.hu/

 

Online JSON Viewer

 

jsonviewer.stack.hu

 

온라인 뷰어에서 보면 

 

이렇게 보인다.

 

'_raw' 이 로우 데이터는 문자열이다.

 

 

문자열을 오브젝트로 바꿔서 찍어본다

 

 

로우 데이터가 파싱되서 나온다.

 

 

raw안에 kakao_account 부분만 출력한다.

 

그 부분만 정상적으로 가져옴

 

그럼 user 에 nickname 과 이미지를 동적으로 넣어준다.

 

콜백하면서 user를 출력하니깐 위에서 넣은 값이 나올것이다. 

 

 

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

let user = {};

passport.use(
    new KakaoStrategy(
        {
            clientID: "6c286dd40f3166ecc7f6dce7ba9469e5",
            clientSecret: "bdvz3V5sKf47U9Sw8M7YYcGzUeeGGkBm", // clientSecret을 사용하지 않는다면 넘기지 말거나 빈 스트링을 넘길 것
            callbackURL: "http://localhost:3030/auth/kakao/callback",
        },
        (accessToken, refreshToken, profile, done) => {
            // 사용자의 정보는 profile에 들어있다.
            let raw = JSON.parse(profile["_raw"]);
            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",
    passport.authenticate("kakao", (err, user) => {
        // console.log(err);
        console.log(user.id);
        console.log(user.nickname);
        console.log(user.profile_image_url);
    })
);

app.get("/", (req, res) => {
    res.send("<h1>hello express!!</h1>");
});

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

 

정상적으로 내가 원하는 값이 출력이 된다.

 

 

-----

 

 

우리는 유니티에서 받아서 넘겨야하는데 지금 코드에서 req.res가 없음 콜백쪽에

 

 

이걸 해결해야한다.

 

이렇게 커스텀 콜백으로 만들어 res.send 를 해준다.

 

정상적으로 응답을 해준다.

 

get 이니깐 받아옴 ㅇㅇ

 

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

let user = {};

passport.use(
    new KakaoStrategy(
        {
            clientID: "6c286dd40f3166ecc7f6dce7ba9469e5",
            clientSecret: "bdvz3V5sKf47U9Sw8M7YYcGzUeeGGkBm", // clientSecret을 사용하지 않는다면 넘기지 말거나 빈 스트링을 넘길 것
            callbackURL: "http://localhost:3030/auth/kakao/callback",
        },
        (accessToken, refreshToken, profile, done) => {
            // 사용자의 정보는 profile에 들어있다.
            let raw = JSON.parse(profile["_raw"]);
            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);
            let json = JSON.stringify(user);
            res.send(json);
        })(req, res);
    });

app.get("/", (req, res) => {
    res.send("<h1>hello express!!</h1>");
});

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

 

여기까지 코드.

 

---

 

이제 외부 서버로 

 

우리 카페 24에서 할 것이다.

 

준희님이 api 서버를 만든 코드를  카페24 깃에 올려야한다.

 

그 서버에 라우터에 접속하면 우리의 id가 찍힌다.

 

카페24로 하면 web.js 로 만들어야지 정상으로 작동한다.

 

----

 

유니티에서 유니 웹뷰 3 임포트하기

 

https://docs.uniwebview.com/

 

UniWebView

 

docs.uniwebview.com

이 사이트 참고하기

 

 

 

프리팹에서 가져오기

 

 

쇼온 스타트 끄기

 

툴바 끄기

 

 

 

기본적으로 웹뷰를 뚫어서 받고, 

 

load 까지해준다. 라우터는 우리의 서버로 해주고

 

웹뷰에서 받으면 그걸 써야한다.

 

 

 

저 RawMessage 가 사이트에 있는 값을 가지고 있는다.

 

 

클래스를 하나 파준다.

 

 

팁- 파일질라에 best http 2 어셋 올려놓음 이거 많이 쓰임 

 

 

선생님 코드를 가져다 쓴다.

 

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 Text txtUserId;
    public Text txtNickName;
    public Image imgThumb;

    public UniWebView webView;

    // 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://thecamper.cafe24app.com/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;
        StartCoroutine(this.WaitForLoadThumb(user.profile_image_url, (texture) => {
            this.imgThumb.sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.zero);
        }));
    }

    private IEnumerator WaitForLoadThumb(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);
    }
}

 

 

 

 

로그인까지 되서 웹뷰가 열리긴하는데 닫는 방법을 모르겠음....

 

-------

 

 

 

 

열리긴하는데 

 

OnMessage 메서드가 안되서 디스트로이드가 안된 것

 

이유는 API 서버에서 uni 웹뷰로 시작해줘야한다 .

 

즉 서버api 에서 send를 할때 유니엡뷰 액션을 해줘야한다. 

 

수정하고 준희님이 다시 깃에 업로드 해줘야한다.

 

즉. 서버에서 send 할때 유니티 웹 액션이 달려서 send 해주는 것이다. 

 

-----

 

문제점 

 

 

1. 서버에서 콜백 해서 찍히는 json를 유니웹뷰에서 못 받앗다

 

그래서 프로토콜이 필요하다. 유니웹뷰에서 만들어 놓은거

 

바로 위에 스크린샷임, "uniwebview://스키마 ? 쿼리" 이런 규약으로만 데이터를 넘길수있게 한다.

 

유니웹뷰에서 새창을 열어서 받을 수 있게한것

 

2. 보낼때 문제 " " " " 이라서 " " " "이 렇게 묶어서 가서 ' " " ' 으로 해서 보내면 해결 된다.

 

 

이렇게 보내야한다. 서버 api에서 수정해야함

app.get("/auth/kakao/callback", (req, res) => {
  passport.authenticate("kakao", (err, user) => {
    let json = JSON.stringify(user);
    res.send(
      `<script>window.location.href = 'uniwebview://test?user=${json}';</script>`
    );
  })(req, res);
});

 

 

----

유니티 app.cs

 

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 Text txtUserId;
    public Text txtNickName;
    public Image imgThumb;

    public UniWebView webView;

    // 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("http://sociallogintest.cafe24app.com/auth/kakao/");
            webView.Show();
        });
    }

    private void WebView_OnMessageReceived(UniWebView webView, UniWebViewMessage message)
    {
        Debug.LogFormat("message.RawMessage: {0}", message.Args["user"]);

        Destroy(webView.gameObject);    //창을 닫는다 

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

        var imgUrl = user.profile_image_url.Insert(4, "://");

        Debug.Log(imgUrl);

        StartCoroutine(this.WaitForLoadThumb(imgUrl, (texture) => {

            Debug.Log(texture);

            this.imgThumb.sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.zero);
        }));
    }

    private IEnumerator WaitForLoadThumb(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);

        Debug.Log(myTexture);

        callback((Texture2D)myTexture);
    }
}

 

서버 

web.js

 

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

let user = {};

passport.use(
  new KakaoStrategy(
    {
      clientID: "e31b7d04bae17785489f51b4cc0adcc5",
      clientSecret: "R0UfKceoaCYVkMfcWda65nNDRGbApgVG", // clientSecret을 사용하지 않는다면 넘기지 말거나 빈 스트링을 넘길 것
      callbackURL: "http://thecamper.cafe24app.com/auth/kakao/callback",
    },
    (accessToken, refreshToken, profile, done) => {
      // 사용자의 정보는 profile에 들어있다.
      let raw = JSON.parse(profile["_raw"]);

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

app.get("/", (req, res) => {
  res.send("<h1>hello express!!</h1>");
});

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

 

 

---

 

결과

 

 

 

-----

 

반응형