Unity Twitter登录接入
相关链接
开发者界面:Use Cases, Tutorials, & Documentation | Twitter Developer Platform
官方文档:Twitter Developer Platform overview | Docs | Twitter Developer Platform
Dashboard:Twitter Developers
接入流程
游戏设置
1、创建开发者账号,需要审核。这块需要注意的是,不同的开发者用途选择的内容不一样,我是用来做 探索API,填写了200字符的说明。提交完成之后等待审核,具体审核时间不知道,我的审核时间大概是12个小时,被拒了,试了三个账号,都被拒了,最后让同事注册了一个公司的。
2、保存SDK的一些相关信息,如下图红框所示。
3、以前有各种针对于android,ios,unity等的sdk,但不知道从哪一年开始就停止了维护,所以现在选择用网页来实现第三方登录。unity可以通过Application.openURL来实现,我这里选择了使用uniwebview插件来实现网页登录,两者区别有一些,但流程是一样的。
登录接入
第一步:请求令牌
官方文档:Log in with Twitter | Docs | Twitter Developer Platform
介绍:
这一步主要是在客户端发送一个post请求,来获取一个令牌,方便后续的用户登录确认。麻烦的地方在于要在客户端生成一个签名,官方也有专门的介绍文档(Creating a signature | Docs | Twitter Developer Platform)。
相关代码:
/// <summary>
/// Encodes the specified text.
/// </summary>
/// <param name="text">The text.</param>
/// <returns>The encoded text.</returns>
public static string UrlEncode(string text)
{
if (string.IsNullOrEmpty(text))
return "";
return string.Concat(Encoding.UTF8.GetBytes(text)
.Select(x => x < 0x80 && "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~"
.Contains(((char)x).ToString()) ? ((char)x).ToString() : ('%' + x.ToString("X2
"))));
}
/// <summary>
/// 获取签名
/// </summary>
/// <returns></returns>
public static string GetSignature(Uri url, IEnumerable<KeyValuePair<string, string>> prm)
{
var key = Encoding.ASCII.GetBytes(
string.Format("{0}&{1}", UrlEncode(APPKeySecret),
UrlEncode(AccessTokenSecret)));
string prmstr = string.Join("&", prm.Select(x => new KeyValuePair<string, string>(UrlEncode(x.Key), UrlEncode(x.Value)))
.Concat(
url.Query.TrimStart('?').Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries)
.Select(x =>
{
var s = x.Split('=');
return new KeyValuePair<string, string>(s[0], s[1]);
})
)
.OrderBy(x => x.Key).ThenBy(x => x.Value)
.Select(x => x.Key + "=" + x.Value));
byte[] msg = Encoding.ASCII.GetBytes(
string.Format("{0}&{1}&{2}",
"POST".ToUpperInvariant(),
UrlEncode(url.GetComponents(UriComponents.Scheme | UriComponents.UserInfo | UriComponents.Host | UriComponents.Port | UriComponents.Path, UriFormat.UriEscaped)),
UrlEncode(prmstr)
));
using (var hs1 = new HMACSHA1(key))
{
return Convert.ToBase64String(hs1.ComputeHash(msg));
}
}
/// <summary>
/// 当前时间戳
/// </summary>
/// <returns></returns>
public static int NowUtcTime()
{
int num = Mathf.CeilToInt((float)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds);
Debug.Log(num);
return num;
}
/// <summary>
/// 第一步
/// 请求token
/// </summary>
/// <returns></returns>
private IEnumerator RequestToken()
{
Uri url = new Uri(TwitterUtility.RequetToken_URI);
string head = CreateAuthorizationHeader(url, null);
WWWForm form = new WWWForm();
form.AddField("oauth_callback", TwitterUtility.REDIRECT_URI);
using (UnityWebRequest request = UnityWebRequest.Post(url, form))
{
request.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded");
request.SetRequestHeader("Authorization", head);
Debug.Log(head);
yield return request.SendWebRequest();
if (request.isHttpError || request.isNetworkError)
{
Debug.Log(TwitterUtility.RequetToken_URI + "========" + request.error);
LoginFail(LoginError.Error);
}
else
{
if (request.responseCode == 200)
{
byte[] results = request.downloadHandler.data;
string backString = Encoding.UTF8.GetString(results);
Debug.Log(backString);
Dictionary<string, string> backData = TwitterUtility.AnalysisBackData(backString);
foreach (var item in backData)
{
Debug.Log(item.Key + "====" + item.Value);
}
Authenticate(backData);
}
else
{
LoginFail(LoginError.Error);
}
}
}
}
第二步:重定向用户
官方文档:使用推特|登录文档|推特开发者平台 (twitter.com)
介绍:
通过浏览器来实现用户登录,并重定向到指定的网址,然后通过网址和URLScheme获取Twitter返回的数据。
第二部麻烦的地方在于使用URLScheme打开app并传递参数,网上有很多现成的文档,还是比较简单的。
相关代码:
安卓端,不用打包新的aar包,直接用Unity本身自带的方法就够了,在androidmanifest文件配置中添加
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!--corresponds to a redirect URL of "aqua://aupay" -->
<data
android:host="test"
android:scheme="test" />
</intent-filter>
/// <summary>
/// 安卓端
/// 网页回调返回
/// </summary>
private void IntentCallback_Android()
{
try
{
AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
AndroidJavaObject intent = currentActivity.Call<AndroidJavaObject>("getIntent");
AndroidJavaObject uri = intent.Call<AndroidJavaObject>("getData");
string query = uri.Call<string>("getQuery");
if (string.IsNullOrEmpty(query))
{
LoginFail(LoginError.UserCancel);
}
else
{
Dictionary<string, string> backData = TwitterUtility.AnalysisBackData(query);
StartCoroutine(AccessTokenHandler(backData));
}
}
catch (Exception)
{
LoginFail(LoginError.UserCancel);
}
}
ios端,需要在xcode中添加urlscheme配置,同时在UnityAppController.mm文件中,添加UnitySendMessage。在网上可以搜到很多例子。
/// <summary>
/// IOS端
/// 网页回调返回
/// </summary>
public void IntentCallback_IOS(string backData)
{
if (!_IsLogin)
{
return;
}
try
{
Debug.Log("ios backData:" + backData);
string query = backData.Split('?')[1];
Dictionary<string, string> queries = TwitterUtility.AnalysisBackData(query);
StartCoroutine(AccessTokenHandler(queries));
}
catch (Exception)
{
LoginFail(LoginError.UserCancel);
}
}
第三步:将请求令牌转换为访问令牌
官方文档:使用推特|登录文档|推特开发者平台 (twitter.com)
介绍:
这一步是在客户端通过Post请求获取可用的访问令牌,没啥难点,跟第一步差不多,注意添加Authorization就行。
相关代码:
/// <summary>
/// 第三步
/// 获取用户基础数据和token
/// </summary>
/// <param name="backData"></param>
/// <returns></returns>
private IEnumerator AccessTokenHandler(Dictionary<string, string> backData)
{
Uri url = new Uri(TwitterUtility.AccessTOKEN_URI);
string head = CreateAuthorizationHeader(url, null, true);
Debug.Log(head);
WWWForm form = new WWWForm();
form.AddField("oauth_verifier", backData["oauth_verifier"]);
form.AddField("oauth_token", backData["oauth_token"]);
using (UnityWebRequest request = UnityWebRequest.Post(url, form))
{
request.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded");
request.SetRequestHeader("Authorization", head);
yield return request.SendWebRequest();
if (request.isHttpError || request.isNetworkError)
{
LoginFail(LoginError.Error);
Debug.Log(TwitterUtility.AccessTOKEN_URI + "===" + request.error);
}
else
{
if (request.responseCode == 200)
{
byte[] results = request.downloadHandler.data;
string backString = Encoding.UTF8.GetString(results);
Debug.Log(backString);
Dictionary<string, string> backData2 = TwitterUtility.AnalysisBackData(backString);
LoginSuccess(backData2);
}
else
{
LoginFail(LoginError.Error);
}
}
}
}
总结
刚开始我们是使用的一个过期的UnitySDk(GitHub - twitter-archive/twitter-kit-unity: Twitter Kit for Unity),官方在好几年前就不维护,现在还可以实现登录,安卓打包啥的基本没啥问题(只试了登录功能),ios在xcode中需要删除UIwebview相关的内容,替换成wkwebview,理论上应该时可以实现的,不熟悉xcode,所以最后放弃了,选择了通过网页登录。
本人是新手,文档做的不好,如果有什么地方有问题,希望大家指正。