P12로 구글 토큰 얻기
시간마다 토큰을 갱신을 해야하지만 이 방법을 사용하면 필요할때만 토큰 생성가능함.
빨간색 부분은 경로나 파일명에 맞게 변경
리소스에 p12 파일 추가해놓고 리소스에서 가져옴.
출저 : http://zavitax.wordpress.com/2012/12/17/logging-in-with-google-service-account-in-c-jwt/
public class GoogleJsonWebToken
{
private const string SCOPE_AUTH_ANDROIDPUBLISHER = @"https://www.googleapis.com/auth/androidpublisher";
public static dynamic GetAccessToken()
{
// header
var header = new { typ = "JWT", alg = "RS256" };
var times = GetExpiryAndIssueDate();
var claimset = new
{
iss = "gather-heroes@api-",
scope = SCOPE_AUTH_ANDROIDPUBLISHER,
aud = @"https://accounts.google.com/o/oauth2/token",
iat = times[0],
exp = times[1],
};
JavaScriptSerializer ser = new JavaScriptSerializer();
// encoded header
var headerSerialized = ser.Serialize(header);
var headerBytes = Encoding.UTF8.GetBytes(headerSerialized);
var headerEncoded = Base64UrlEncode(headerBytes);
///////////////
///certificate
////////////////
byte[] dataKey = null;
using (var stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("ProjectNameSpace. Resources.Google.Play.Android.Developer-906baXXXX.p12"))
{
dataKey = new byte[stream.Length];
stream.Read(dataKey, 0, dataKey.Length);
}
X509Certificate2 certificate = new X509Certificate2(dataKey, "notasecret");
// encoded claimset
var claimsetSerialized = ser.Serialize(claimset);
var claimsetBytes = Encoding.UTF8.GetBytes(claimsetSerialized);
var claimsetEncoded = Base64UrlEncode(claimsetBytes);
// input
var input = headerEncoded + "." + claimsetEncoded;
var inputBytes = Encoding.UTF8.GetBytes(input);
// signiture
var rsa = certificate.PrivateKey as RSACryptoServiceProvider;
var cspParam = new CspParameters
{
KeyContainerName = rsa.CspKeyContainerInfo.KeyContainerName,
KeyNumber = rsa.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange ? 1 : 2
};
var aescsp = new RSACryptoServiceProvider(cspParam) { PersistKeyInCsp = false };
var signatureBytes = aescsp.SignData(inputBytes, "SHA256");
var signatureEncoded = Base64UrlEncode(signatureBytes);
// jwt
var jwt = headerEncoded + "." + claimsetEncoded + "." + signatureEncoded;
var client = new WebClient();
client.Encoding = Encoding.UTF8;
var uri = @"https://accounts.google.com/o/oauth2/token";
var content = new NameValueCollection();
content["assertion"] = jwt;
content["grant_type"] = "urn:ietf:params:oauth:grant-type:jwt-bearer";
string response = Encoding.UTF8.GetString(client.UploadValues(uri, "POST", content));
var result = ser.Deserialize<dynamic>(response);
return result;
}
private static int[] GetExpiryAndIssueDate()
{
var utc0 = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
var issueTime = DateTime.UtcNow;
var iat = (int)issueTime.Subtract(utc0).TotalSeconds;
var exp = (int)issueTime.AddMinutes(55).Subtract(utc0).TotalSeconds;
return new[] { iat, exp };
}
private static string Base64UrlEncode(byte[] input)
{
var output = Convert.ToBase64String(input);
output = output.Split('=')[0]; // Remove any trailing '='s
output = output.Replace('+', '-'); // 62nd char of encoding
output = output.Replace('/', '_'); // 63rd char of encoding
return output;
}
}
얻은 토큰으로 인앱 영수증 검증
{
var auth = GoogleJsonWebToken.GetAccessToken();
string url = "https://www.googleapis.com/androidpublisher/v2/applications/"
+ this.Params["appid"] + "/purchases/products/" + this.Params["productid"] + "/tokens/" + this.Params["token"] + "?access_token=" + auth["access_token"];
System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
var client = new System.Net.Http.HttpClient();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
var req = client.GetAsync(new Uri(url));
try
{
if (req.Result.IsSuccessStatusCode)
{
var result = req.Result.Content.ReadAsStringAsync().Result;
Receipt _result = JsonConvert.DeserializeObject<Receipt>(result);
if (_result.PurchaseState == 0)
{
/*
아이템 지급 및 로그 기록
*/
}
}
}
catch
{
}
}
'개발관련 > C#' 카테고리의 다른 글
ObjectSerialize (0) | 2017.08.10 |
---|---|
Aes 암호화/복호화 (0) | 2017.08.10 |
모든 타입 xmlWriter (0) | 2017.08.10 |
XmlSerializer (0) | 2017.08.03 |
Http Handler 비동기 처리 (0) | 2017.07.25 |