Firebase API 호출 Wrapper() 만들어 활용하기
www.ashishvishwakarma.com/creating-c-sharp-wrapper-over-firebase-api-for-basic-crud/
Firebase API 호출 시, 구글 서비스를 통해 Access-token 적용해 보기
Firebase 읽기 / 쓰기 액세스는 RULES 에서 볼 수 있듯이 기본적으로 보호됩니다 .
{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}
IAM 의 서비스 계정에서 키를 발급 받습니다.
console.cloud.google.com/projectselector2/iam-admin/serviceaccounts?supportedpurview=project
프로젝트를 선택합니다.
키관리를 선택합니다.
키 추가를 통해서 키가 없었으면 새 키 만들기를 선택합니다. 선택 후 브라우저에서 json 형태로 파일을 받습니다.
1번 : 받은 json 내용물을 복사해서 key.json 파일을 열어서 본문에 붙여 넣습니다.
2번 : key.json 파일은 출력 디렉터리로 복사를 "항상 복사" 로 설정합니다.
3번 : program.cs 파일을 열어서 키 값 위치 인, json 파일 위치를 기재해 줍니다.
이제 실행하면, 이를 통해 access_token 값을 가져와서 firebase 의 데이터를 추가, 수정, 삭제, 조회까지 가능합니다.
using Google.Apis.Auth.OAuth2;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
namespace FirebaseNet.Auth
{
class AuthHelper
{
public static string ACCESS_TOKEN { get; set; }
private static string jsonKeyFilePath;
private static string[] scopes;
private static async Task<string> GetAccessTokenFromJSONKeyAsync(string jsonKeyFilePath, params string[] scopes)
{
using (var stream = new FileStream(jsonKeyFilePath, FileMode.Open, FileAccess.Read))
{
return await GoogleCredential
.FromStream(stream) // Loads key file
.CreateScoped(scopes) // Gathers scopes requested
.UnderlyingCredential // Gets the credentials
.GetAccessTokenForRequestAsync(); // Gets the Access Token
}
}
public static void GenenateAccessToken(string jsonKeyFilePath, params string[] scopes)
{
AuthHelper.jsonKeyFilePath = jsonKeyFilePath;
if (scopes.Length == 0)
AuthHelper.scopes = new string[] { "https://www.googleapis.com/auth/firebase", "https://www.googleapis.com/auth/userinfo.email" };
else
AuthHelper.scopes = scopes;
ACCESS_TOKEN = GetAccessTokenFromJSONKeyAsync(jsonKeyFilePath, AuthHelper.scopes).Result;
}
public static void RefreshToken()
{
if (!string.IsNullOrEmpty(ACCESS_TOKEN))
ACCESS_TOKEN = GetAccessTokenFromJSONKeyAsync(jsonKeyFilePath, scopes).Result;
else
throw new InvalidOperationException("Unauthorised! Generate a token first.");
}
}
}
RequestHelper() 를 보면 호출시 access_token 값을 전송하여 이를 검증받아 firebase 로 부터 데이터를 핸들링 가능합니다.
//-----------------------------------------------------------------------
// <copyright file="UtilityHelper.cs" company="AshishVishwakarma.com">
// Github/AshV
// </copyright>
// <author>Ashish Vishwakarma</author>
//-----------------------------------------------------------------------
namespace FirebaseNet.Database
{
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using FirebaseNet.Auth;
/// <summary>
/// Utility Helper Class
/// </summary>
class UtilityHelper
{
/// <summary>
/// User Agent Header in HTTP Request
/// </summary>
private const string USER_AGENT = "firebase-net/0.2";
/// <summary>
/// Validates a URI
/// </summary>
/// <param name="url">URI as string</param>
/// <returns>True if valid</returns>
public static bool ValidateURI(string url)
{
Uri locurl;
if (System.Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out locurl))
{
if (
!(locurl.IsAbsoluteUri &&
(locurl.Scheme == "http" || locurl.Scheme == "https")) ||
!locurl.IsAbsoluteUri)
{
return false;
}
}
else
{
return false;
}
return true;
}
/// <summary>
/// Validates JSON string
/// </summary>
/// <param name="inJSON">JSON to be validatedd</param>
/// <param name="output">Valid JSON or Error Message</param>
/// <returns>True if valid</returns>
public static bool TryParseJSON(string inJSON, out string output)
{
try
{
JToken parsedJSON = JToken.Parse(inJSON);
output = parsedJSON.ToString();
return true;
}
catch (Exception ex)
{
output = ex.Message;
return false;
}
}
/// <summary>
/// Makes Asynchronus HTTP requests
/// </summary>
/// <param name="method">HTTP method</param>
/// <param name="uri">URI of resource</param>
/// <param name="json">JSON string</param>
/// <returns>HTTP Responce as Task</returns>
public static Task<HttpResponseMessage> RequestHelper(HttpMethod method, Uri uri, string json = null)
{
if (!string.IsNullOrEmpty(AuthHelper.ACCESS_TOKEN))
uri = new Uri($"{uri}?access_token={AuthHelper.ACCESS_TOKEN}");
var client = new HttpClient();
var msg = new HttpRequestMessage(method, uri);
msg.Headers.Add("user-agent", USER_AGENT);
if (json != null)
{
msg.Content = new StringContent(
json,
UnicodeEncoding.UTF8,
"application/json");
}
return client.SendAsync(msg);
}
}
}
오류 발생시 refresh_token 으로 호출하여 다시 access-token 을 전송하여 처리합니다.
//-----------------------------------------------------------------------
// <copyright file="FirebaseRequest.cs" company="AshishVishwakarma.com">
// Github/AshV
// </copyright>
// <author>Ashish Vishwakarma</author>
//-----------------------------------------------------------------------
namespace FirebaseNet.Database
{
using FirebaseNet.Auth;
using System;
using System.Net;
using System.Net.Http;
/// <summary>
/// Firebase Request
/// </summary>
class FirebaseRequest
{
/// <summary>
/// Suffix to be added in each resource URI
/// </summary>
private const string JSON_SUFFIX = ".json";
/// <summary>
/// Initializes a new instance of the <see cref="FirebaseRequest"/> class
/// </summary>
/// <param name="method">HTTP Method</param>
/// <param name="uri">URI of resource</param>
/// <param name="jsonString">JSON string</param>
public FirebaseRequest(HttpMethod method, string uri, string jsonString = null)
{
this.Method = method;
this.JSON = jsonString;
if (uri.Replace("/", string.Empty).EndsWith("firebaseio.com"))
{
this.Uri = uri + '/' + JSON_SUFFIX;
}
else
{
this.Uri = uri + JSON_SUFFIX;
}
}
/// <summary>
/// Gets or sets HTTP Method
/// </summary>
private HttpMethod Method { get; set; }
/// <summary>
/// Gets or sets JSON string
/// </summary>
private string JSON { get; set; }
/// <summary>
/// Gets or sets URI
/// </summary>
private string Uri { get; set; }
/// <summary>
/// Executes a HTTP requests
/// </summary>
/// <returns>Firebase Response</returns>
public FirebaseResponse Execute()
{
Uri requestURI;
if (UtilityHelper.ValidateURI(this.Uri))
{
requestURI = new Uri(this.Uri);
}
else
{
return new FirebaseResponse(false, "Provided Firebase path is not a valid HTTP/S URL");
}
string json = null;
if (this.JSON != null)
{
if (!UtilityHelper.TryParseJSON(this.JSON, out json))
{
return new FirebaseResponse(false, string.Format("Invalid JSON : {0}", json));
}
}
var response = UtilityHelper.RequestHelper(this.Method, requestURI, json);
response.Wait();
var result = response.Result;
if (!result.IsSuccessStatusCode && result.StatusCode.Equals(HttpStatusCode.Unauthorized))
{
AuthHelper.RefreshToken();
response = UtilityHelper.RequestHelper(this.Method, requestURI, json);
response.Wait();
result = response.Result;
}
var firebaseResponse = new FirebaseResponse()
{
HttpResponse = result,
ErrorMessage = result.StatusCode.ToString() + " : " + result.ReasonPhrase,
Success = response.Result.IsSuccessStatusCode
};
if (this.Method.Equals(HttpMethod.Get))
{
var content = result.Content.ReadAsStringAsync();
content.Wait();
firebaseResponse.JSONContent = content.Result;
}
return firebaseResponse;
}
}
}
.NET C# CryptographicException 에서 공급자 형식 provider type 이 명시되지 않았습니다. 오류 발생 해결 방안. (0) | 2021.05.11 |
---|---|
c# 으로 telegram 텔레그램 chat bot 메시지 전송하기 (2) | 2021.04.26 |
C# 의 AES/CBC/PKCS5Padding 으로 암복호화 하기 (1) | 2021.04.14 |
C# Dapper - model 을 만들지 않고 곧바로 dynamic 키워드 사용 방법 (0) | 2020.12.22 |
json string 문자열을 object 로 변환하기 ( json to object c# ) (6) | 2020.11.25 |