Desktop App + UWP App + UWP App Service를 이용한 MS live account 인증

Desktop App + UWP App + UWP App Service를 이용해서 기본적인 MS Account
로그인을 구현했다.

이번 프로젝트에선 회원가입을 받지 않을 생각이다. 회원 가입용 웹사이트도 만들지 않는다. 이전에는 두 가지 방식을 사용했다.

  1. 웹사이트에서 회원가입을 받으면 웹사이트에서 Game DB에 연결하여 계정 생성
  2. steam로그인일 경우 클라이언트에서 steam API를 통해 steam id를 얻는다. 게임서버로 steam id를 전송하고 게임서버는 서버용 steam API를 이용해서 이 id가 유요한지-게임을 정말 구입했는지, steam 클라이언트로 게임을 실행한게 맞는지-를 체크한다. 맞으면 st+steam id로 계정명을 만들어서 로그인 처리한다. Game DB에 해당 계정명(st+steam id)이 있으면 그대로 로그인 처리, 없으면 즉시 새로운 계정을 만든다.

이번에는 스팀에 출시할지 어떨지 불확실하다. 아마 힘들것 같다.
그리고 웹사이트는 만들 생각이 없다. 개발할 여력도, 관리할 여력도 없다.
그래서 구글계정이나 MS계정을 사용할 생각이다. 구글이나 MS계정을 steam id처럼 사용하는 것이다.

기본 전략은 다음과 같다.

  1. 클라이언트에서 웹으로 인증을 받고 토큰을 받으면 게임서버로 토큰을 보낸다.
  2. 게임 서버는 토큰으로 구글이나 MS의 웹사이트에 접속해서 인증을 받고 email을 얻어온다. 그 email을 계정명으로 사용한다.

UWP개발 경험과 One Drive앱 개발 경험이 있고 MS기술이 다루기 편하므로 우선 MS계정 로그인부터 구현하기로 했다.

그런데 현재까지도 win32(데스크탑앱) + C++ 프로젝트에서 live connect에 접속해서 인증받는 방법은 찾지 못했다. 데스크탑앱에서 .NET을 쓰면 가능할지도 모르겠다. 그런데 .NET으로 하는건 내 입장에서 보면 UWP앱을 C++로 개발해서 데스크탑에서 호출하는것과 다르지 않다. 오히려 UWP앱으로 만들고 통신하는 쪽이 나한텐 더 편하다.
물론 UWP앱을 따로 설치해줘야하는게 문제다. 이건 데스크탑 브릿지를 사용해서 하나의 패키지로 묶으면 해결되는데 이전까지는 꽤 귀찮은 작업이었다.
마침 요 근래 Visual Studio 2017이 업데이트 되면서 Desktop Bridge를 위한 프로젝트 템플릿이 추가되었다. 이 프로젝트 템플릿을 사용하면 기존 데스크탑앱 코드와 UWP앱 코드를 손쉽게 같이 패키징 할수 있다. OK. 이걸로 해결이다.

Voxel Horizon은 현재 UWP버전과 데스크탑 버전을 함께 유지하고 있다.
각각의 버전은 다음과 같이 로그인을 처리한다.

[개발버전(데스크탑)]
디버깅과 유지보수를 위해 Desktop Bridge로 패키징하지 않는다. 순수한 데스크탑앱의 형태를 유지한다. 따라서 로그인용 UWP앱을 따로 설치해야한다.

[데스크탑 배포판]
로그인용 UWP앱과 데스크탑앱을 Desktop Bridge로 함께 패키징한다. 로그인용 UWP앱의 코드를 변경할 필요는 없다. 물론 UWP앱을 먼저 설치할 필요도 없다.

[UWP배포판]
별도의 로그인용 앱은 필요없다. 로그인 기능은 게임 클라이언트 안에 코드로 구현한다.

그리고 몇 일간 테스트와 사전 학습으로 시간을 보냈다.

[기술적 문제 – UWP App의 샌드박스 체계, 프로세스간 통신불가]
UWP앱과 데스크탑앱 사이에 통신을 해야한다. 어떤 방법으로든 통신을 해야한다. UWP앱에서 얻어온 토큰을 데스크탑앱에 전달해야한다. 데스크탑앱에서 토큰을 받아서 접속을 완료하고나면 UWP앱은 필요가 없다. 따라서 UWP앱을 종료시켜야 하는데 데스크탑앱에서 UWP앱을 종료시킬수도 없다. 뭔가 메시지를 보내서 종료해달라고 요청해야한다.

그런데 UWP앱은 샌드박스로 돌아간다. 보안을 위해 어떤 외부 프로세스와 통신도 허용하지 않는다.
시도해 보고 실패한 방법들은 다음과 같다.

  1. socket 통신 – 불가. UWP앱이 소켓을 통한 프로세스간 통신을 허용하지 않음. ip 127.0.0.1아 아니더라도 프로세스간 연결이면 무조건 차단.
  2. Shared Memory – 불가. access denied.
  3. Named Pipe – 불가. access denied.
  4. OpenEvent()를 이용한 Event 공유 – 불가. access denied.

[해결 – App Service]
이 외에 몇가지 방법이 더 있지만 어차피 다 실패할게 학실해서 그만두었다.
허용되는 방법은 딱 한가지가 있다. UWP앱에 App Service를 구현하면 된다.

순수 UWP앱이든 Desktop Bridge든 package manifest에 하나 이상의 서비스를 정의할 수 있다. 물론 서비스를 구현하는 코드는 작성해야하고 dll형태로 빌드되어서 패키지 안에 포함되어야 한다.

App Service로 다음과 같이 통신할 수 있다.

  1. UWP App App Service UWP App
  2. UWP App App Service Desktop App(같은 패키지 안에 존재하는)
  3. UWP App App Service Desktop App(패키지 안에 존재하지 않는)

3번의 경우는 처음 시도했을때 실패했다. 그래서 불가능한줄 알았으나 여러가지로 더 테스트 해보니 콘솔모드 데스크탑앱에서만 불가능하고 윈도우 모두 데스크탑앱에선 가능했다. 아마도 HWND가 있느냐 여부가 관건인것 같다.

OK. 이제 제대로 구현을 시작해보자.

[구현]

  1. MS live account에 접속하고 토큰을 받아올 UWP앱을 만든다.
  2. 여기에 외부 프로세스에서 접근할 수 있도록 App Service를 추가한다.
  3. manifest에 프로토콜을 정의해서 uri로 이 앱을 실행할 수 있도록 한다.
  4. 데스크탑앱이 실행되면 내가 정의판 프로토콜 uri로 LaunchUri() 함수를 호출, 위에서 만든 UWP앱을 실행한다.
  5. 데스크탑앱은 UWP앱 실행후 UWP앱 안에 구현한 서비스에 접속한다.
  6. 이 시점에서 App Service UWP앱과 데스크탑앱 양쪽 connection을 모두 유지하고 있다.
  7. UWP앱에서 MS Live Account 접속을 시도하고 접속에 성공하면 토큰을 받는다. App Service를 통해서(UWP앱 -> App Service -> 데스크탑앱) 데스크탑앱으로 토큰을 보낸다.
  8. 데스크탑앱은 토큰을 받으면 HttpClient를 사용해서 live connect에 토큰 인증을 요청한다.
  9. 토큰 인증에 성공하면 email을 비롯한 기본 프로필이 json데이터로 넘어온다.
  10. 데스크탑앱에서 UWP앱으로 (데스크탑앱 -> App Service -> UWP앱) 메시지를 보내서 스스로 종료하도록 요청한다. 메시지를 받으면 UWP앱은 종료한다.

샘플로 이렇게 만들었고 게임 프로젝트 적용 시에는 클라이언트에선 live connect에 토큰 인증을 요청지 않는다. 게임 서버로 토큰을 보내고, 게임서버가 live connect에서 토큰을 인증한다.


2017_1105_auth_01

데스크탑앱 실행. 데스크탑앱이 LaunchUri()로 로그인용 UWP앱을 실행했다.


2017_1105_auth_02

UWP앱에서 로그인.


2017_1105_auth_03

로그인 성공후 토큰을 받아왔다.


2017_1105_auth_04

UWP앱서 데스크탑앱으로 토큰을 전송했다. 데스크탑앱은 토큰을 가지고 live connect에 인증요청을 했고 이메일과 이름을 얻어왔다. 그리고 UWP앱에 메시지를 보내서 UWP앱은 스스로 종료했다.

이제 실제 게임 클라이언트와 서버에 적용하는 일이 남았다.


Desktop App + UWP App + UWP App Service를 이용한 MS live account 인증”에 대한 답글 7개

  1. 안녕하세요. 여기에 글을 남겨도 되는지 모르겠는데 제일 최신 글 같아서 적어요.
    오늘 CAD 관련 Inhouse를 만들다가 Spec.이 바뀌는 바람에 멘붕에 빠져 멀할까 생각하다 즐겨찾기에 등록된 유영천님 블로그에 와서 여러 글을 읽었습니다.
    기술관련 내용은 거의 모르겠네요 ㅎㅎ. 하지만 그중에서도 Code로 철학하는 애라든지, 도장찍는 게임회사, 게임엔진 리얼한 그래픽 이야기는 공감이 가네요. 삼각형 하나라도 직접 찍어봤는지랑 쓸데없는 고민할 시간에 무조건 만들어라.. 라는 글을 읽을 때는 뜨끔했습니다.
    사실 저 같은 경우 프로그래밍이랑 전혀 연관없는 공부를 하고 나이 30때 부터 프로그래밍을 시작해서 4년정도 작은 Inhouse만 여러개 개발했는데(주업은 설계지원 입니다.) 그렇다 보니 기초가 없어서 개발하고 싶은 것이 있어도 이걸로 할까 저걸로 할까 매일 고민만 하면서 시간을 보내는 것 같습니다. ㅎㅎ
    어떻게 생각하실지 모르겠지만. 저도 저만의 게임을 만들어 보고 싶습니다. 되도록 엔진도 제 손으로 만들고 싶구요 머 유형천님 같은 화려한 그런 게임은 아니구요 최종적으로 택틱스 오우거 같은 ISO 뷰 타입의 2D 게임을 만들어 보고 싶습니다. 천천히.. 수년이 걸리더라도요. 물론 지금 실력으로는 테트리스도 힘들겠지만요.
    회사에서는 VB6(ㅠㅠ)이랑 C#을 주로 사용하는데 별로 쓰고 싶지 않고요. 관심있는 언어는 C언어랑 Go언어 입니다. C언어는 시간 날때마다 공부하고 있고, Go의 경우 요즘 여기저기 자료 수집 중입니다. 될 수 있으면 C나 Go만 사용해서 짜보고 싶은데 가능할까요?
    여튼 짧은 조언이라도 해주시면 감사히 받겠습니다.

    좋아요

    1. 응원합니다. 그런데 게임개발에선 때려죽여도 c++은 피해갈수 없습니다. Go로는 사실상 할수 있는게 없고요. C++컴파일러를 사용하는 C언어같은 느낌으로 거의 C처럼 짤수는 있지만 최소한 sdk와 api때문에라도 C++을 전혀 사용하지 않을수는 없습니다.

      좋아요

      1. 답장 감사합니다~ 아 그렇군요 결국 C++을 공부해야 겠네요 ㅎㅎㅎ win32 api, opengl, sdl 이정도 사용하면 되지 않을까 생각 했는데… 최소한의 sdk와 api가 어떤 것인지 궁금하네요 ㅎㅎ;; 여튼 감사합니다 C++은 피할 수 없는 것이군요.

        좋아요

  2. 문제가 계속 안풀려서 검색하다가 비슷한 구조로 구현된 사례 같아서 오게 되었습니다. 앱서비스가 몇 초 안가서 자꾸 끊어지는데 기존의 데스크탑앱은 패키지 패밀리 네임이란 개념이 없어서 연결을 송신은 해도 수신은 못하고, 지속적으로 연결되어 통신해야할 경우에도 해법이 잘안보이네요. 이런 문제는 없었는지 다른 방안이 있는건지 소중한 의견 공유해주시면 좋겠습니다. 연락처가 트위터밖에 없어서 팔로우는 했지만 메시지는 보낼수 없네요ㅜㅠ

    좋아요

    1. 데스크탑측 연결과 uwp측 연결을 앱서비스측에서 모두 유지하고 있고요. 그래서uwp측에 메시지를 보낼땐 메시지에 헤더를 붙여서 앱서비스에 보내면 앱서비스측에서 다시 uwp앱으로 중계해주고 uwp에서 데스크탑앱으로 메시지를 보낼때도 그렇게 처리합니다. 그리고 이게 브레이크 포인트를 찍거나 해보면 끊길때가 있는데요. 저도 끊기는 정확한 원인은 모르겠습니다.앱서비스가 바로 응답하지 않으면 os가 죽이는것 같은데요. API 문제일것 같은데 현재로선 연결을 장시간 유지하는건 어려울것 같아요. 트위터 아이디 알려주시면 제쪽에서 팔로우 하든가 아니면 페북으로 연락주세요. 페북은
      https://facebook.com/megayuchi 입니다.

      좋아요

      1. 답변감사합니다. 윈도가 제공하는 샘플은 데스크탑앱과 연결이 몇분이 지나도 계속 유지되고 있어서 (물론 제 프로그램은 호출자와 피호출자, 호출 구조가 좀 다르긴 하지만) 되지않을까해서 계속 삽질을 해봤었고 확장실행 객체를 써봐도 끊어지는건 여전해서 문의드려봤습니다. 검색해보면 같은 문제로 고생중인 개발자들도 몇 있는것 같구요. 근데 페북주소는 (한글 제외하고 입력해도) 없는 페이지라고 나오네요. 제가 오늘 1111번째로 팔로우한 vitamintoday 입니다. 트위터쪽지로 더 구체적인 문제점이나 상태를 공유해보도록 하겠습니다. 윈도10 개발플랫폼을 계속 써야할지 정말 답답한 순간이네요 안쓸수도 없고;;

        좋아요

답글 남기기

댓글을 게시하려면 다음의 방법 중 하나를 사용하여 로그인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중