- 任意のオブジェクトに以下のスクリプトをアタッチして使用する
- AuthorizedRequest メソッドに URL とリクエスト成功時のコールバック関数などを指定すると、自動で認証を行った上でリクエストを送信してくれる。
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using MiniJSON;
using System;
public class APIManager : MonoBehaviour {
public string TokenUrl = "http://127.0.0.1:3000/oauth/token";
public string UsersUrl = "http://127.0.0.1:3000/users/100";
public string client_id = "07461c1f68870ea090ed20af49d0680782950119213e2a1af9e1f653c688dca3";
public string client_secret = "20dea83f022c9e2a0e6fbec1da0e9c0e20c40e1bf09d2e8db029b461653a88bd";
public string username = "user1@example.com";
public string password = "password";
public string AccessToken;
public long ExpiresIn;
public long CreatedAt;
public string RefreshToken;
private static readonly DateTime UNIX_EPOCH = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public DateTime ExpiresAt;
void Start () {
StartCoroutine(GetUsers());
}
<summary>
</summary>
public IEnumerator GetUsers () {
yield return StartCoroutine(AuthorizedRequest(
url: UsersUrl,
onSuccess: (WWW www) => {
Debug.Log(www.text);
Debug.Log(www.error);
foreach (var kv in www.responseHeaders) {
Debug.Log(string.Format("{0} : {1}", kv.Key, kv.Value));
}
}
));
}
<summary>
</summary>
<param name="url"></param>
<param name="form"></param>
<param name="headers"></param>
<param name="onSuccess"></param>
<param name="onError"></param>
public IEnumerator AuthorizedRequest (string url, WWWForm form = null, Dictionary<string, string> headers = null, System.Action<WWW> onSuccess = null, System.Action onError = null) {
if (string.IsNullOrEmpty(AccessToken)) {
var tokenGet = TokenGet();
yield return StartCoroutine(tokenGet);
if (Request.RequestIsError(tokenGet)) {
yield break;
}
}
if (ExpiresAt < DateTime.Now) {
var tokenRefresh = TokenRefresh();
yield return StartCoroutine(tokenRefresh);
if (Request.RequestIsError(tokenRefresh)) {
yield break;
}
}
if (headers == null) {
headers = new Dictionary<string, string>();
headers.Add("Authorization", string.Format("Bearer {0}", AccessToken));
}
var request = new Request(url, form, headers, onSuccess, onError);
yield return StartCoroutine(request.Send());
yield return request;
}
<summary>
</summary>
IEnumerator TokenGet () {
var form = new WWWForm();
form.AddField("grant_type", "password");
form.AddField("username", username);
form.AddField("password", password);
form.AddField("client_id", client_id);
form.AddField("client_secret", client_secret);
var request = new Request(url: TokenUrl, form: form, onSuccess: TokenUpdate);
yield return StartCoroutine(request.Send());
yield return request;
}
<summary>
</summary>
IEnumerator TokenRefresh () {
var form = new WWWForm();
form.AddField("grant_type", "refresh_token");
form.AddField("refresh_token", RefreshToken);
form.AddField("client_id", client_id);
form.AddField("client_secret", client_secret);
var request = new Request(url: TokenUrl, form: form, onSuccess: TokenUpdate);
yield return StartCoroutine(request.Send());
yield return request;
}
<summary>
</summary>
<param name="www"></param>
private void TokenUpdate (WWW www) {
var jsonDict = Request.WWWToJson(www);
AccessToken = (string)jsonDict["access_token"];
ExpiresIn = (long)jsonDict["expires_in"];
CreatedAt = (long)jsonDict["created_at"];
RefreshToken = (string)jsonDict["refresh_token"];
ExpiresAt = UNIX_EPOCH.AddSeconds(CreatedAt + ExpiresIn).ToLocalTime();
}
private class Request {
public bool IsError { private set; get; }
private float TIMEOUT = 5f;
private string url;
private byte[] formdata;
private Dictionary<string, string> headers;
private System.Action<WWW> onSuccess;
private System.Action onError;
public Request (string url, WWWForm form = null, Dictionary<string, string> headers = null, System.Action<WWW> onSuccess = null, System.Action onError = null) {
this.url = url;
this.formdata = form == null ? null : form.data;
this.headers = headers;
this.onSuccess = onSuccess == null ? (WWW www) => {} : onSuccess;
this.onError = onError == null ? () => {} : onError;
}
public IEnumerator Send () {
var www = new WWW(url, formdata, headers);
var endtime = Time.realtimeSinceStartup + TIMEOUT;
while (!www.isDone || Time.realtimeSinceStartup < endtime) {
yield return null;
}
if (WWWIsError(www)) {
this.IsError = true;
onError();
} else {
this.IsError = false;
onSuccess(www);
}
yield return this;
}
private bool WWWIsError (WWW www) {
return !string.IsNullOrEmpty(www.error);
}
public static Dictionary<string, object> WWWToJson (WWW www) {
return Json.Deserialize(www.text) as Dictionary<string, object>;
}
public static bool RequestIsError (IEnumerator request) {
return ((Request)request.Current).IsError;
}
}
}