리눅스 서버에서, http의 80번 포트로 요청이 들어왔을 때, 내가 사용하는 Port로 redirection 시켜서 쓰기 위한 코드는 다음과 같다. 



$ sudo iptables -A PREROUTING -t nat -i eth0 -p tcp —dport 80 -j REDIRECT —to-port [내가 사용하는 Portnum]


$ sudo apt-get install curl

curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -

$ sudo apt-get install -y nodejs



여기서 버전은 4.x, 5.x 이렇게 바꿀 수가 있다. 

apt-get으로 설치하는 것보다는 이렇게 Nodesource를 이용해서 설치하는 것이 더 좋다. 



AWS 우분투 머신 인스턴스 생성 후에 
terminal 에서 ssh 접속을 하려고 할 때 

->  ssh -i Example1.pem ec2-user@52.79.104.18

Permission denied (publickey).    


라는 에러가 떴다. 

두 가지 경우가 있는데, key가 잘못 되었거나, 사용자 이름이 잘못되었을 때이다. 


나의 경우 Amazon Linux AMI를 쓰는 예제를 보고 따라해서 ec2-user라는 사용자 이름을 사용했지만
각 AMI에 따라 사용자 이름이 다르다는 것을 


여기서 알 수 있다. 


  • Amazon Linux AMI의 경우 사용자 이름은 ec2-user입니다.

  • RHEL5 AMI의 경우 사용자 이름은 root 또는 ec2-user입니다.

  • Ubuntu AMI의 경우 사용자 이름은 ubuntu입니다.

  • Fedora AMI의 경우 사용자 이름은 fedora 또는 ec2-user입니다.

  • SUSE Linux의 경우 사용자 이름은 root 또는 ec2-user입니다.

  • ec2-user 및 root를 사용할 수 없는 경우 AMI 공급자에게 문의하십시오


즉 나는 우분투를 쓰기 때문에 ubuntu라고 사용자 이름을 작성 했어야 하는 것이다. 








개발을 하다보면 시간, 날짜와 관련된 일을 할 때가 종종 있다. 

개발 중 파이썬 Datetime 모듈을 이용해서 사용한 몇가지를 정리해야겠다.



1) 현재시간 보다 (얼만큼) 전, 후 



한국 시간의 경우 utc보다 9시간 뒤이다. 즉 utc가 오전 9시라면, 한국시간은 저녁 6시인 것이다. 

utc 시간을 이용해 9시간 뒤의 한국시간을 구하기 위해서는 utc시간에 +9시간을 하면 되는 것이다. 

그럴 때 쓰는 것이 datetime.timedelta 이다.




이런식으로 계산할 수 있다. 물론 timedelta() 괄호 안에 parameter로는 minutes, days, 등이 들어갈 수 있겠다. 





2) String으로 표현된 datetime을 datetime 객체로 변환 시키기



클라이언트로 부터 클라이언트의 시간을 받았지만 그 시간의 형태는 string이다. 이것을 datetime 객체로 바꿀 필요가 있다


그리고 나서 type을 확인해보면 datetime.datetime 임을 알 수 있다. 






3) datetime 간의 시간 차이


내가 직면한 문제는 서버의 시간은 utc를 쓰지만 클라이언트는 클라이언트 개인 시간을 쓰기 때문에, 

서버 시간과 클라이언트 시간의 차이를 구해서 그 시간만큼을 timegap으로 사용해야 하는 것이었다. 


간단하게 차이 연산으로 해결할 수가 있다. 



여기서 



라고 확인을 해보면 

32406.608232 이라는 값이 나온다. 


반대로 utc_time - kor_time을 해서 똑같이 확인을 해보면

-32406.608232 이라는 값이 나온다.


한국 시간이 utc 시간보다 더 빠르기 때문에 한국 시간에서 utc 시간을 빼면 양수가 나오고, 반대의 경우 음수가 나오는 것이다.

이것은 초 단위 시간 차이이기 때문에 분 차이로 알고 싶으면 /60, 시간 차이로 알고 싶으면 /3600을 하면 된다. 


나는 시간을 알고 싶기 때문에 /3600을 해보겠다. 


결과는 9.00183562 즉 9시간이다 라는 것을 알 수 있다. 

필자는 단순히 몇 시간 차이가 나는지를 구할 필요가 있었기 때문에, 반올림을 하여서

9라는 결과값을 얻을 수 있었다. 










게임 내 인앱 결제의 보안성을 위해서 클라이언트가 지급 받은 영수증과 Google API를 이용하여서
그 영수증이 유효한 영수증인지를 확인할 필요가 있다.

서버 검증이 진행되는 순서는 다음과 같다.
  1. 클라이언트의 요청이 오면 developerPayload(임의의 String)를 발급하고, 서버 DB등에 저장을 한다.
  2. 클라이언트가 서버에게 발급받은 developerPayload를 이용해서 구글 플레이에 결제요청을 하고, 그 결과로 받은 developerPayload를 서버에 보낸다.
  3. 서버는 클라이언트에게 받은 developerPayload가 자신이 발급한 developerPayload가 맞는지 확인한다. 
  4. developerPayload가 일치하는지를 확인하고 그 결과를 보내준다.
  5. 일치한다면 클라이언트는 서버에 영수증 정보를 보내고, 서버는 그 영수s증 정보를 가지고 Google API에 검증요청을 한다.
  6. 검증이 완료되면 Client에게 상품을 지급한다.

여기서 3번 이후 과정에 대해서 자세히 설명해 보겠다.



구글 개발자 콘솔, 구글 플레이 개발자 콘솔 설정 

먼저 구글 API를 사용하기 위해서는 Credential을 만들어야 한다.

에서 프로젝트를 생성을 한다.



생성을 한 후에 좌측 상단에 있는 메뉴 버튼을 눌러서 ‘권한’ 으로 이동한다. 


여기서 서비스 계정 만들기를 클릭한다. 



이렇게 생성을 하면 자동으로 내 컴퓨터에 json 파일이 다운로드 받아진다. 
이 json 파일 내부에는 여러가지 정보가 기술되어 있다. 그리고 이 json 파일은 프로젝트 내부에서 접근할 수 있도록 관리를 한다. 

그리고 API 관리자 개요에 들어가서 만든 프로젝트를 사용하도록 사용 버튼을 누른다.

여기까지가 google 개발자 콘솔에서 하는 작업이다.


이제 실제로 앱을 등록하는 Google Play Console에 들어간다.
왼쪽에 있는 설정을 누른다.
API 액세스에 들어가면 시작하기가 나오고 밑에 프로젝트들이 나열되어 있는데 이전에 만든 프로젝트를 클릭해서 사용하게 한다. 

그러면 이제 사용준비가 완료가 된 것이다.



서버구현

파이썬을 이용하기 때문에 구글 api를 사용하기 위해서 

     $ pip install --upgrade google-api-python-client

를 이용해서 클라이언트 모듈을 설치를 한다. 



이제 구글 API를 사용하기 위해서는 먼저 사용자가 API를 사용하기에 적합한 사용자인지를 검증해야한다. 
그래서 Credentials 객체를 생성하도록 한다. 우리는 json파일을 받았기 때문에 다음과 같이 코드를 작성한다. 

from oauth2client.service_account import ServiceAccountCredentials
scopes = ['https://www.googleapis.com/auth/androidpublisher']

credentials = ServiceAccountCredentials.from_json_keyfile_name(
    'app/google/Idletower-174c42ca2fb9.json'scopes)


생성한 credentials 객체의 authorize 메소드를 이용해서 http 인스턴스를 생성하도록 한다. 

from httplib2 import Http

http_auth = credentials.authorize(Http())

여기서 

Client가 구글 플레이 스토어로 부터 받는 영수증 정보는 다음과 같다. 
{
    "orderId":"1299912121692121212121.1320812112121",
    "packageName":"com.test.runrunrun",
    "productId":"com.test.runrunrun.item_001",
    "purchaseTime":1393377621833,
    "purchaseState":0,
    "purchaseToken":"sekadakadaaxgjhsrLn61wGoyAl..._8-l8zsUhVpY7o7Zq08s"
}
- orderId : 주문번호
- packageName : 앱의 패키지명(구글 내에서는 중복되지 않습니다.)
- productId : 상품 ID
- purchaseTime : 구매시각 ms 입니다.
- purchaseState : 구매상태
- purchaseToken : 구매 token



위의 정보 중에 Server가 필요로 하는 것은 세 가지 이다.
     packageName,  productId,  purchaseToken


googleapiclient.discovery.build를 이용해서 build를 다음과 같이한다. 
그리고 클라이언트에서 받아온 productId, packageName, token을 이용해서 api 호출을 한다. 

from googleapiclient.discovery import build

androidpublisher = build('androidpublisher''v2'credentials=credentialshttp=http_auth)
product = androidpublisher.purchases().products().\
    get(productId=productIdpackageName=packageNametoken=token)

purchase = product.execute()


purchase는 다음과 같은 정보를 나타내고 JSON 객체이기 때문에 바로 사용이 가능하다. 

{
 
"kind": "androidpublisher#productPurchase",
  "purchaseTimeMillis": long,
  "purchaseState": integer, // 0 이면 구매 된 것, 1이면 cancel 된것
  "consumptionState": integer, // 0 이면 아직 consume이 되지 않았고, 1이면 consumed된 것.
  "developerPayload": string
}

이 것을 이용해서 구매 확인을 하고 물품을 지급하면 된다. 





http://gyus.me/?p=418

http://flask-docs-kr.readthedocs.org/ko/latest/errorhandling.html



출처 : 스포카 기술 블로그

https://spoqa.github.io/2012/08/03/about-python-coding-convention.html



+ Recent posts