Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
232 views
in Technique[技术] by (71.8m points)

c# - OAuth2 Authentication and Operations in Unity

I need to implement OAuth2 authentication and some operations for a Windows Mobile application in Unity. I have managed to make it work as a console application (using .NET 4.0 and above), however, Unity only supports up until .NET 3.5, so simply copying the code didn't work. Is there any way to make it work in Unity? Here is my authentication code:

private static async Task<string> GetAccessToken()
    {
        using (var client = new HttpClient())
        {
            client.BaseAddress = new Uri("https://someurl.com");
            var content = new FormUrlEncodedContent(new[]
            {
                new KeyValuePair<string, string>("grant_type", "client_credentials"),
                new KeyValuePair<string, string>("client_id", "login-secret"),
                new KeyValuePair<string, string>("client_secret", "secretpassword")
            });
            var result = await client.PostAsync("/oauth/token", content);
            string resultContent = await result.Content.ReadAsStringAsync();
            var json = JObject.Parse(resultContent);
            return json["access_token"].ToString();
        }
    }

And this is one of my OAuth2 functions:

private static async Task<string> GetMeasurements(string id, DateTime from, DateTime to)
    {
        using (var client = new HttpClient())
        {
            client.BaseAddress = new Uri("https://someurl.com");
            var content = new FormUrlEncodedContent(new[]
            {
                new KeyValuePair<string, string>("MeasurePoints", id),
                new KeyValuePair<string, string>("Sampling", "Auto"),
                new KeyValuePair<string, string>("From", from.ToString("yyyy-MM-ddTHH:mm:ssZ")),
                new KeyValuePair<string, string>("To", to.ToString("yyyy-MM-ddTHH:mm:ssZ"))
            });
            client.DefaultRequestHeaders.Add("Authorization", "Bearer " + GetAccessToken().Result);
            var result = await client.PostAsync("/api/v2/Measurements", content);
            string resultContent = await result.Content.ReadAsStringAsync();
            var rootArray = JArray.Parse(resultContent);
            string measurements = "";
            foreach (JObject item in rootArray)
            {
                measurements = item.GetValue("Measurements").ToString();
            }

            return measurements;
        }
    }

If you have any suggestions, I will be grateful for eternity. Thanks!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It's not really that hard to translate to old .NET version. You can use Unity's WWW or UnityWebRequest API. Any of them should do it.

1.Replace HttpClient with UnityWebRequest.

2.Replace KeyValuePair, with Dictionary.

3.Replace DefaultRequestHeaders with SetRequestHeader.

4.Replace client.PostAsync with UnityWebRequest.Send

5.For Json, use unity's JsonUtility

6.For Json array in your GetMeasurements function, use the JsonHelper class from this post.

That's it. I was able to do a quick porting. Didn't test it but it was able to compile and should get you started.

GetAccessToken function:

[Serializable]
public class TokenClassName
{
    public string access_token;
}

private static IEnumerator GetAccessToken(Action<string> result)
{
    Dictionary<string, string> content = new Dictionary<string, string>();
    //Fill key and value
    content.Add("grant_type", "client_credentials");
    content.Add("client_id", "login-secret");
    content.Add("client_secret", "secretpassword");

    UnityWebRequest www = UnityWebRequest.Post("https://someurl.com//oauth/token", content);
    //Send request
    yield return www.Send();

    if (!www.isError)
    {
        string resultContent = www.downloadHandler.text;
        TokenClassName json = JsonUtility.FromJson<TokenClassName>(resultContent);

        //Return result
        result(json.access_token);
    }
    else
    {
        //Return null
        result("");
    }
}

GetMeasurements function:

[Serializable]
public class MeasurementClassName
{
    public string Measurements;
}

private static IEnumerator GetMeasurements(string id, DateTime from, DateTime to, Action<string> result)
{
    Dictionary<string, string> content = new Dictionary<string, string>();
    //Fill key and value
    content.Add("MeasurePoints", id);
    content.Add("Sampling", "Auto");
    content.Add("From", from.ToString("yyyy-MM-ddTHH:mm:ssZ"));
    content.Add("To", to.ToString("yyyy-MM-ddTHH:mm:ssZ"));
    content.Add("client_secret", "secretpassword");

    UnityWebRequest www = UnityWebRequest.Post("https://someurl.com/api/v2/Measurements", content);

    string token = null;

    yield return GetAccessToken((tokenResult) => { token = tokenResult; });

    www.SetRequestHeader("Authorization", "Bearer " + token);
    www.Send();

    if (!www.isError)
    {
        string resultContent = www.downloadHandler.text;
        MeasurementClassName[] rootArray = JsonHelper.FromJson<MeasurementClassName>(resultContent);

        string measurements = "";
        foreach (MeasurementClassName item in rootArray)
        {
            measurements = item.Measurements;
        }

        //Return result
        result(measurements);
    }
    else
    {
        //Return null
        result("");
    }
}

Usage:

string id = "";
DateTime from = new DateTime();
DateTime to = new DateTime();

StartCoroutine(GetMeasurements(id, from, to, (measurementResult) =>
{
    string measurement = measurementResult;

    //Do something with measurement
    UnityEngine.Debug.Log(measurement);

}));

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...