com.taptap.sdk.login 4.6.1-beta.9 → 4.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Mobile/Editor/NativeDependencies.xml +3 -4
- package/Runtime/Public/TapTapLogin.cs +1 -1
- package/Standalone/Runtime/Internal/Tracker/TapLoginTracker.cs +16 -6
- package/Standalone/Runtime/Internal2/LoginService.cs +20 -0
- package/Standalone/Runtime/Internal2/TapLoginStandaloneImpl.cs +352 -90
- package/Standalone/Runtime/Internal2/UI/QRCodeController.cs +2 -1
- package/Standalone/Runtime/Internal2/UI/WebController.cs +2 -1
- package/package.json +2 -2
|
@@ -4,14 +4,13 @@
|
|
|
4
4
|
<repositories>
|
|
5
5
|
<repository>https://repo.maven.apache.org/maven2</repository>
|
|
6
6
|
</repositories>
|
|
7
|
-
<androidPackage spec="com.taptap.sdk:tap-login-unity:4.6.1
|
|
7
|
+
<androidPackage spec="com.taptap.sdk:tap-login-unity:4.6.1"/>
|
|
8
8
|
</androidPackages>
|
|
9
9
|
<iosPods>
|
|
10
10
|
<sources>
|
|
11
11
|
<source>https://github.com/CocoaPods/Specs.git</source>
|
|
12
12
|
</sources>
|
|
13
|
-
<iosPod name="
|
|
14
|
-
<iosPod name="
|
|
15
|
-
<iosPod name="TapTapGidSDK" version="~> 4.5.2" bitcodeEnabled="false" addToAllTargets="false"/>
|
|
13
|
+
<iosPod name="TapTapLoginSDK" version="~> 4.5.5" bitcodeEnabled="false" addToAllTargets="false"/>
|
|
14
|
+
<iosPod name="TapTapGidSDK" version="~> 4.5.5" bitcodeEnabled="false" addToAllTargets="false"/>
|
|
16
15
|
</iosPods>
|
|
17
16
|
</dependencies>
|
|
@@ -7,7 +7,7 @@ namespace TapSDK.Login
|
|
|
7
7
|
public class TapTapLogin
|
|
8
8
|
{
|
|
9
9
|
|
|
10
|
-
public static readonly string Version = "4.6.1
|
|
10
|
+
public static readonly string Version = "4.6.1";
|
|
11
11
|
|
|
12
12
|
public const string TAP_LOGIN_SCOPE_BASIC_INFO = "basic_info";
|
|
13
13
|
public const string TAP_LOGIN_SCOPE_PUBLIC_PROFILE = "public_profile";
|
|
@@ -14,6 +14,10 @@ namespace TapSDK.Login.Standalone.Internal
|
|
|
14
14
|
private const string ACTION_FAIL = "fail";
|
|
15
15
|
private const string ACTION_CANCEL = "cancel";
|
|
16
16
|
|
|
17
|
+
internal static string LOGIN_TYPE_CLIENT = "pc_client";
|
|
18
|
+
internal static string LOGIN_TYPE_CODE = "pc_code";
|
|
19
|
+
internal static string LOGIN_TYPE_BROWSER = "pc_browser";
|
|
20
|
+
|
|
17
21
|
private static TapLoginTracker instance;
|
|
18
22
|
|
|
19
23
|
private TapOpenlogStandalone openlog;
|
|
@@ -40,13 +44,16 @@ namespace TapSDK.Login.Standalone.Internal
|
|
|
40
44
|
ReportLog(ACTION_INIT);
|
|
41
45
|
}
|
|
42
46
|
|
|
43
|
-
internal void TrackStart(string funcNace, string seesionId)
|
|
47
|
+
internal void TrackStart(string funcNace, string seesionId, string loginType = null)
|
|
44
48
|
{
|
|
45
49
|
Dictionary<string, string> parameters = new Dictionary<string, string>
|
|
46
50
|
{
|
|
47
51
|
{ "func_name", funcNace },
|
|
48
|
-
{ "
|
|
52
|
+
{ "session_id", seesionId },
|
|
49
53
|
};
|
|
54
|
+
if (loginType != null) {
|
|
55
|
+
parameters["login_type"] = loginType;
|
|
56
|
+
}
|
|
50
57
|
ReportLog(ACTION_START, new Dictionary<string, string>()
|
|
51
58
|
{
|
|
52
59
|
{ "args", JsonConvert.SerializeObject(parameters) }
|
|
@@ -58,7 +65,7 @@ namespace TapSDK.Login.Standalone.Internal
|
|
|
58
65
|
Dictionary<string, string> parameters = new Dictionary<string, string>
|
|
59
66
|
{
|
|
60
67
|
{ "func_name", funcNace },
|
|
61
|
-
{ "
|
|
68
|
+
{ "session_id", seesionId },
|
|
62
69
|
{ "login_type", loginType }
|
|
63
70
|
};
|
|
64
71
|
ReportLog(ACTION_SUCCESS, new Dictionary<string, string>()
|
|
@@ -67,13 +74,16 @@ namespace TapSDK.Login.Standalone.Internal
|
|
|
67
74
|
});
|
|
68
75
|
}
|
|
69
76
|
|
|
70
|
-
internal void TrackCancel(string funcNace, string seesionId)
|
|
77
|
+
internal void TrackCancel(string funcNace, string seesionId, string loginType = null)
|
|
71
78
|
{
|
|
72
79
|
Dictionary<string, string> parameters = new Dictionary<string, string>
|
|
73
80
|
{
|
|
74
81
|
{ "func_name", funcNace },
|
|
75
|
-
{ "
|
|
82
|
+
{ "session_id", seesionId },
|
|
76
83
|
};
|
|
84
|
+
if (loginType != null) {
|
|
85
|
+
parameters["login_type"] = loginType;
|
|
86
|
+
}
|
|
77
87
|
ReportLog(ACTION_CANCEL, new Dictionary<string, string>()
|
|
78
88
|
{
|
|
79
89
|
{ "args", JsonConvert.SerializeObject(parameters) }
|
|
@@ -85,7 +95,7 @@ namespace TapSDK.Login.Standalone.Internal
|
|
|
85
95
|
Dictionary<string, string> parameters = new Dictionary<string, string>
|
|
86
96
|
{
|
|
87
97
|
{ "func_name", funcNace },
|
|
88
|
-
{ "
|
|
98
|
+
{ "session_id", seesionId },
|
|
89
99
|
{ "error_code", errorCode.ToString() },
|
|
90
100
|
{ "error_msg", errorMessage },
|
|
91
101
|
{ "login_type", loginType }
|
|
@@ -59,6 +59,26 @@ namespace TapSDK.Login.Internal
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
public static async Task<TokenData> Authorize(string clientId, string code, string codeVerify) {
|
|
63
|
+
Dictionary<string, string> data = new Dictionary<string, string> {
|
|
64
|
+
{ "client_id", clientId },
|
|
65
|
+
{ "grant_type", "authorization_code" },
|
|
66
|
+
{ "secret_type", "hmac-sha-1" },
|
|
67
|
+
{ "code", code },
|
|
68
|
+
{ "redirect_uri", "tapoauth://authorize" },
|
|
69
|
+
{ "code_verifier", codeVerify }
|
|
70
|
+
};
|
|
71
|
+
TapHttpResult<TokenData> result = await tapHttp.PostFormAsync<TokenData>(TapTapSdk.CurrentRegion.TokenUrl(), form: data);
|
|
72
|
+
if (result.IsSuccess)
|
|
73
|
+
{
|
|
74
|
+
return result.Data;
|
|
75
|
+
}
|
|
76
|
+
else
|
|
77
|
+
{
|
|
78
|
+
throw result.HttpException;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
62
82
|
public static async Task<TokenData> RequestScanQRCodeResult(string clientId, string deviceCode)
|
|
63
83
|
{
|
|
64
84
|
Dictionary<string, string> data = new Dictionary<string, string> {
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
using System;
|
|
2
2
|
using System.Collections.Generic;
|
|
3
|
+
using System.Collections.Specialized;
|
|
3
4
|
using System.Linq;
|
|
5
|
+
using System.Net.Http.Headers;
|
|
6
|
+
using System.Threading;
|
|
4
7
|
using System.Threading.Tasks;
|
|
5
8
|
using TapSDK.Core;
|
|
6
9
|
using TapSDK.Core.Internal.Utils;
|
|
10
|
+
using TapSDK.Core.Standalone;
|
|
7
11
|
using TapSDK.Core.Standalone.Internal.Http;
|
|
8
12
|
using TapSDK.Login.Internal.Http;
|
|
9
13
|
using TapSDK.Login.Standalone;
|
|
@@ -19,9 +23,12 @@ namespace TapSDK.Login.Internal
|
|
|
19
23
|
// 当前是否正在登录中
|
|
20
24
|
private volatile bool IsLogging = false;
|
|
21
25
|
|
|
26
|
+
// 本地缓存的用户信息是否和 Tap 启动器一致
|
|
27
|
+
internal static bool isCacheUserSameWithTapClient = true;
|
|
28
|
+
|
|
22
29
|
private TapLoginStandaloneImpl()
|
|
23
30
|
{
|
|
24
|
-
|
|
31
|
+
|
|
25
32
|
}
|
|
26
33
|
|
|
27
34
|
public static TapLoginStandaloneImpl Instance
|
|
@@ -35,11 +42,15 @@ namespace TapSDK.Login.Internal
|
|
|
35
42
|
return instance;
|
|
36
43
|
}
|
|
37
44
|
}
|
|
38
|
-
|
|
45
|
+
|
|
39
46
|
public void Init(string clientId, TapTapRegionType regionType)
|
|
40
47
|
{
|
|
41
48
|
TapTapSdk.SDKInitialize(clientId, regionType == TapTapRegionType.CN);
|
|
42
49
|
AccountManager.Instance.Init();
|
|
50
|
+
|
|
51
|
+
TapLogger.Debug("RegisterListenerForTapClientCheck ");
|
|
52
|
+
RegisterListenerForTapClientCheck();
|
|
53
|
+
|
|
43
54
|
_ = CheckAndRefreshToken();
|
|
44
55
|
TapLoginTracker.Instance.TrackInit();
|
|
45
56
|
}
|
|
@@ -47,14 +58,15 @@ namespace TapSDK.Login.Internal
|
|
|
47
58
|
public Task<TapTapAccount> Login(string[] scopes)
|
|
48
59
|
{
|
|
49
60
|
// 正在登录时,返回登录异常
|
|
50
|
-
if(IsLogging)
|
|
61
|
+
if (IsLogging)
|
|
62
|
+
{
|
|
51
63
|
var defaultTcs = new TaskCompletionSource<TapTapAccount>();
|
|
52
|
-
defaultTcs.TrySetException(new TapException((int)
|
|
64
|
+
defaultTcs.TrySetException(new TapException((int)TapErrorCode.ERROR_CODE_LOGOUT_INVALID_LOGIN_STATE, "Currently logging in"));
|
|
53
65
|
return defaultTcs.Task;
|
|
54
66
|
}
|
|
55
67
|
IsLogging = true;
|
|
56
68
|
string sessionId = Guid.NewGuid().ToString();
|
|
57
|
-
|
|
69
|
+
|
|
58
70
|
|
|
59
71
|
if (!scopes.Contains(TapTapLogin.TAP_LOGIN_SCOPE_PUBLIC_PROFILE))
|
|
60
72
|
{
|
|
@@ -67,94 +79,294 @@ namespace TapSDK.Login.Internal
|
|
|
67
79
|
{
|
|
68
80
|
scopes = scopes.Append(complianceScope).ToArray();
|
|
69
81
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
82
|
+
|
|
83
|
+
// 是否使用 Tap 启动器登录
|
|
84
|
+
bool isNeedLoginByClient = TapCoreStandalone.IsNeedLoginByTapClient();
|
|
85
|
+
|
|
86
|
+
if (isNeedLoginByClient)
|
|
87
|
+
{
|
|
88
|
+
TapLoginTracker.Instance.TrackStart("loginWithScopes", sessionId, TapLoginTracker.LOGIN_TYPE_CLIENT);
|
|
89
|
+
string info = "{\"device_id\":\"" + SystemInfo.deviceModel + "\"}";
|
|
90
|
+
string sdkUA = "client_id=" + TapTapSdk.ClientId + "&uuid=" + SystemInfo.deviceUniqueIdentifier;
|
|
91
|
+
TapLogger.Debug("LoginWithScopes start in mainthread = " + Thread.CurrentThread.ManagedThreadId);
|
|
92
|
+
return Task.Run(async () =>
|
|
93
|
+
{
|
|
94
|
+
string responseType = "code";
|
|
95
|
+
string redirectUri = "tapoauth://authorize";
|
|
96
|
+
string state = Guid.NewGuid().ToString("N");
|
|
97
|
+
string codeVerifier = CodeUtil.GenerateCodeVerifier();
|
|
98
|
+
string codeChallenge = CodeUtil.GetCodeChallenge(codeVerifier);
|
|
99
|
+
string versionCode = TapTapSDK.Version;
|
|
100
|
+
string codeChallengeMethod = "S256";
|
|
101
|
+
TapCoreStandalone.TapLoginResponseByTapClient response = await TapCoreStandalone.LoginWithScopesAsync(scopes,
|
|
102
|
+
responseType, redirectUri, codeChallenge, state, codeChallengeMethod, versionCode, sdkUA, info);
|
|
103
|
+
TapLogger.Debug("start handle login result");
|
|
104
|
+
TapLogger.Debug("LoginWithScopes handle in mainthread = " + Thread.CurrentThread.ManagedThreadId);
|
|
105
|
+
|
|
106
|
+
if (response.isCancel)
|
|
107
|
+
{
|
|
108
|
+
IsLogging = false;
|
|
109
|
+
TapLoginTracker.Instance.TrackCancel("loginWithScopes", sessionId, TapLoginTracker.LOGIN_TYPE_CLIENT);
|
|
110
|
+
throw new TaskCanceledException();
|
|
111
|
+
}
|
|
112
|
+
else if (response.isFail || string.IsNullOrEmpty(response.redirectUri))
|
|
113
|
+
{
|
|
77
114
|
IsLogging = false;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
115
|
+
TapLoginTracker.Instance.TrackFailure("loginWithScopes", sessionId, TapLoginTracker.LOGIN_TYPE_CLIENT, (int)TapErrorCode.ERROR_CODE_UNDEFINED, response.errorMsg ?? "未知错误");
|
|
116
|
+
throw new TapException((int)TapErrorCode.ERROR_CODE_UNDEFINED, response.errorMsg ?? "未知错误");
|
|
117
|
+
}
|
|
118
|
+
else
|
|
119
|
+
{
|
|
120
|
+
TapLogger.Debug("login success prepare get token");
|
|
121
|
+
try
|
|
122
|
+
{
|
|
123
|
+
Uri uri = new Uri(response.redirectUri);
|
|
124
|
+
NameValueCollection queryPairs = UrlUtils.ParseQueryString(uri.Query);
|
|
125
|
+
string code = queryPairs["code"];
|
|
126
|
+
string uriState = queryPairs["state"];
|
|
127
|
+
string error = queryPairs["error"];
|
|
128
|
+
if (string.IsNullOrEmpty(error) && uriState == state && !string.IsNullOrEmpty(code))
|
|
91
129
|
{
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
130
|
+
TokenData tokenData = await LoginService.Authorize(TapTapSdk.ClientId, code, codeVerifier);
|
|
131
|
+
if (tokenData == null)
|
|
132
|
+
{
|
|
133
|
+
throw new TapException((int)TapErrorCode.ERROR_CODE_UNDEFINED, "UnKnow Error");
|
|
134
|
+
}else {
|
|
135
|
+
// 将 TokenData 转化为 AccessToken
|
|
136
|
+
AccessToken refreshToken = new AccessToken
|
|
137
|
+
{
|
|
138
|
+
kid = tokenData.Kid,
|
|
139
|
+
tokenType = tokenData.TokenType,
|
|
140
|
+
macKey = tokenData.MacKey,
|
|
141
|
+
macAlgorithm = tokenData.MacAlgorithm,
|
|
142
|
+
scopeSet = tokenData.Scopes
|
|
143
|
+
};
|
|
144
|
+
try
|
|
145
|
+
{
|
|
146
|
+
ProfileData profileData = await LoginService.GetProfile(TapTapSdk.ClientId, refreshToken);
|
|
147
|
+
if (profileData != null)
|
|
148
|
+
{
|
|
149
|
+
AccountManager.Instance.Account = new TapTapAccount(
|
|
150
|
+
refreshToken, profileData.OpenId, profileData.UnionId, profileData.Name, profileData.Avatar,
|
|
151
|
+
profileData.Email);
|
|
152
|
+
IsLogging = false;
|
|
153
|
+
TapLoginTracker.Instance.TrackSuccess("loginWithScopes", sessionId, TapLoginTracker.LOGIN_TYPE_CLIENT);
|
|
154
|
+
return AccountManager.Instance.Account;
|
|
155
|
+
}
|
|
156
|
+
else
|
|
157
|
+
{
|
|
158
|
+
throw new TapException((int)TapErrorCode.ERROR_CODE_UNDEFINED, "UnKnow Error");
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
catch (Exception e)
|
|
162
|
+
{
|
|
163
|
+
throw new TapException((int)TapErrorCode.ERROR_CODE_UNDEFINED, "UnKnow Error " + e.Message);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
98
166
|
}
|
|
99
167
|
else
|
|
100
168
|
{
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
tcs.TrySetException(new TapException((int) TapErrorCode.ERROR_CODE_UNDEFINED, "UnKnow Error"));
|
|
169
|
+
TapLogger.Debug("login success prepare get token but get error " + error);
|
|
170
|
+
throw new TapException((int)TapErrorCode.ERROR_CODE_UNDEFINED, error ?? "数据解析异常");
|
|
104
171
|
}
|
|
105
|
-
}
|
|
106
|
-
|
|
172
|
+
}
|
|
173
|
+
catch (Exception ex)
|
|
174
|
+
{
|
|
107
175
|
IsLogging = false;
|
|
108
|
-
|
|
176
|
+
TapLogger.Debug("login success prepare get token fail " + ex.StackTrace);
|
|
177
|
+
TapLoginTracker.Instance.TrackFailure("loginWithScopes", sessionId, TapLoginTracker.LOGIN_TYPE_CLIENT, (int)TapErrorCode.ERROR_CODE_UNDEFINED, ex.Message ?? "UnKnow Error");
|
|
178
|
+
throw new TapException((int)TapErrorCode.ERROR_CODE_UNDEFINED, ex.StackTrace);
|
|
109
179
|
}
|
|
110
180
|
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
else
|
|
184
|
+
{
|
|
185
|
+
TapLoginTracker.Instance.TrackStart("loginWithScopes", sessionId);
|
|
186
|
+
TaskCompletionSource<TapTapAccount> tcs = new TaskCompletionSource<TapTapAccount>();
|
|
187
|
+
LoginPanelController.OpenParams openParams = new LoginPanelController.OpenParams
|
|
188
|
+
{
|
|
189
|
+
ClientId = TapTapSdk.ClientId,
|
|
190
|
+
Scopes = scopes,
|
|
191
|
+
OnAuth = async (tokenData, loginType) =>
|
|
192
|
+
{
|
|
193
|
+
if (tokenData == null)
|
|
194
|
+
{
|
|
195
|
+
TapLoginTracker.Instance.TrackFailure("loginWithScopes", sessionId, loginType, (int)TapErrorCode.ERROR_CODE_UNDEFINED, "UnKnow Error");
|
|
196
|
+
IsLogging = false;
|
|
197
|
+
tcs.TrySetException(new TapException((int)TapErrorCode.ERROR_CODE_UNDEFINED, "UnKnow Error"));
|
|
198
|
+
}
|
|
199
|
+
else
|
|
200
|
+
{
|
|
201
|
+
// 将 TokenData 转化为 AccessToken
|
|
202
|
+
AccessToken refreshToken = new AccessToken
|
|
203
|
+
{
|
|
204
|
+
kid = tokenData.Kid,
|
|
205
|
+
tokenType = tokenData.TokenType,
|
|
206
|
+
macKey = tokenData.MacKey,
|
|
207
|
+
macAlgorithm = tokenData.MacAlgorithm,
|
|
208
|
+
scopeSet = tokenData.Scopes
|
|
209
|
+
};
|
|
210
|
+
try
|
|
211
|
+
{
|
|
212
|
+
ProfileData profileData = await LoginService.GetProfile(TapTapSdk.ClientId, refreshToken);
|
|
213
|
+
if (profileData != null)
|
|
214
|
+
{
|
|
215
|
+
TapLoginTracker.Instance.TrackSuccess("loginWithScopes", sessionId, loginType);
|
|
216
|
+
AccountManager.Instance.Account = new TapTapAccount(
|
|
217
|
+
refreshToken, profileData.OpenId, profileData.UnionId, profileData.Name, profileData.Avatar,
|
|
218
|
+
profileData.Email);
|
|
219
|
+
IsLogging = false;
|
|
220
|
+
tcs.TrySetResult(AccountManager.Instance.Account);
|
|
221
|
+
}
|
|
222
|
+
else
|
|
223
|
+
{
|
|
224
|
+
TapLoginTracker.Instance.TrackFailure("loginWithScopes", sessionId, loginType, (int)TapErrorCode.ERROR_CODE_UNDEFINED, "UnKnow Error");
|
|
225
|
+
IsLogging = false;
|
|
226
|
+
tcs.TrySetException(new TapException((int)TapErrorCode.ERROR_CODE_UNDEFINED, "UnKnow Error"));
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
catch (Exception e)
|
|
230
|
+
{
|
|
231
|
+
TapLoginTracker.Instance.TrackFailure("loginWithScopes", sessionId, loginType, (int)TapErrorCode.ERROR_CODE_UNDEFINED, "UnKnow Error");
|
|
232
|
+
IsLogging = false;
|
|
233
|
+
tcs.TrySetException(new TapException((int)TapErrorCode.ERROR_CODE_UNDEFINED, "UnKnow Error " + e.Message));
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
OnError = (e, loginType) =>
|
|
238
|
+
{
|
|
239
|
+
TapLoginTracker.Instance.TrackFailure("loginWithScopes", sessionId, loginType, e.Code, e.Message);
|
|
240
|
+
IsLogging = false;
|
|
241
|
+
tcs.TrySetException(e);
|
|
242
|
+
},
|
|
243
|
+
OnClose = () =>
|
|
244
|
+
{
|
|
245
|
+
TapLoginTracker.Instance.TrackCancel("loginWithScopes", sessionId);
|
|
246
|
+
IsLogging = false;
|
|
247
|
+
tcs.TrySetCanceled();
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
TapSDK.UI.UIManager.Instance.OpenUI<LoginPanelController>("Prefabs/TapLogin/LoginPanel", openParams);
|
|
251
|
+
return tcs.Task;
|
|
252
|
+
}
|
|
125
253
|
}
|
|
126
|
-
|
|
254
|
+
|
|
127
255
|
public Task<AccessToken> Authorize(string[] scopes = null)
|
|
128
256
|
{
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
257
|
+
// 是否使用 Tap 启动器登录
|
|
258
|
+
bool isNeedLoginByClient = TapCoreStandalone.IsNeedLoginByTapClient();
|
|
259
|
+
|
|
260
|
+
if (isNeedLoginByClient)
|
|
261
|
+
{
|
|
262
|
+
string info = "{\"device_id\":\"" + SystemInfo.deviceModel + "\"}";
|
|
263
|
+
string sdkUA = "client_id=" + TapTapSdk.ClientId + "&uuid=" + SystemInfo.deviceUniqueIdentifier;
|
|
264
|
+
TapLogger.Debug("LoginWithScopes start in mainthread = " + Thread.CurrentThread.ManagedThreadId);
|
|
265
|
+
return Task.Run(async () =>
|
|
266
|
+
{
|
|
267
|
+
string responseType = "code";
|
|
268
|
+
string redirectUri = "tapoauth://authorize";
|
|
269
|
+
string state = Guid.NewGuid().ToString("N");
|
|
270
|
+
string codeVerifier = CodeUtil.GenerateCodeVerifier();
|
|
271
|
+
string codeChallenge = CodeUtil.GetCodeChallenge(codeVerifier);
|
|
272
|
+
string versionCode = TapTapSDK.Version;
|
|
273
|
+
string codeChallengeMethod = "S256";
|
|
274
|
+
TapCoreStandalone.TapLoginResponseByTapClient response = await TapCoreStandalone.LoginWithScopesAsync(scopes,
|
|
275
|
+
responseType, redirectUri, codeChallenge, state, codeChallengeMethod, versionCode, sdkUA, info);
|
|
276
|
+
TapLogger.Debug("start handle login result");
|
|
277
|
+
TapLogger.Debug("LoginWithScopes handle in mainthread = " + Thread.CurrentThread.ManagedThreadId);
|
|
278
|
+
|
|
279
|
+
if (response.isCancel)
|
|
280
|
+
{
|
|
281
|
+
throw new TaskCanceledException();
|
|
146
282
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
283
|
+
else if (response.isFail || string.IsNullOrEmpty(response.redirectUri))
|
|
284
|
+
{
|
|
285
|
+
throw new TapException((int)TapErrorCode.ERROR_CODE_UNDEFINED, response.errorMsg ?? "未知错误");
|
|
286
|
+
}
|
|
287
|
+
else
|
|
288
|
+
{
|
|
289
|
+
TapLogger.Debug("login success prepare get token");
|
|
290
|
+
try
|
|
291
|
+
{
|
|
292
|
+
Uri uri = new Uri(response.redirectUri);
|
|
293
|
+
NameValueCollection queryPairs = UrlUtils.ParseQueryString(uri.Query);
|
|
294
|
+
string code = queryPairs["code"];
|
|
295
|
+
string uriState = queryPairs["state"];
|
|
296
|
+
string error = queryPairs["error"];
|
|
297
|
+
if (string.IsNullOrEmpty(error) && uriState == state && !string.IsNullOrEmpty(code))
|
|
298
|
+
{
|
|
299
|
+
TokenData tokenData = await LoginService.Authorize(TapTapSdk.ClientId, code, codeVerifier);
|
|
300
|
+
if (tokenData == null)
|
|
301
|
+
{
|
|
302
|
+
throw new TapException((int)TapErrorCode.ERROR_CODE_UNDEFINED, "UnKnow Error");
|
|
303
|
+
}else {
|
|
304
|
+
// 将 TokenData 转化为 AccessToken
|
|
305
|
+
AccessToken refreshToken = new AccessToken
|
|
306
|
+
{
|
|
307
|
+
kid = tokenData.Kid,
|
|
308
|
+
tokenType = tokenData.TokenType,
|
|
309
|
+
macKey = tokenData.MacKey,
|
|
310
|
+
macAlgorithm = tokenData.MacAlgorithm,
|
|
311
|
+
scopeSet = tokenData.Scopes
|
|
312
|
+
};
|
|
313
|
+
return refreshToken;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
else
|
|
317
|
+
{
|
|
318
|
+
TapLogger.Debug("login success prepare get token but get error " + error);
|
|
319
|
+
throw new TapException((int)TapErrorCode.ERROR_CODE_UNDEFINED, error ?? "数据解析异常");
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
catch (Exception ex)
|
|
323
|
+
{
|
|
324
|
+
TapLogger.Debug("login success prepare get token fail " + ex.StackTrace);
|
|
325
|
+
throw new TapException((int)TapErrorCode.ERROR_CODE_UNDEFINED, ex.StackTrace);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
else
|
|
331
|
+
{
|
|
332
|
+
TaskCompletionSource<AccessToken> tcs = new TaskCompletionSource<AccessToken>();
|
|
333
|
+
LoginPanelController.OpenParams openParams = new LoginPanelController.OpenParams
|
|
334
|
+
{
|
|
335
|
+
ClientId = TapTapSdk.ClientId,
|
|
336
|
+
Scopes = new HashSet<string>(scopes).ToArray(),
|
|
337
|
+
OnAuth = (tokenData, loginType) =>
|
|
338
|
+
{
|
|
339
|
+
if (tokenData == null)
|
|
340
|
+
{
|
|
341
|
+
tcs.TrySetException(new TapException((int)TapErrorCode.ERROR_CODE_UNDEFINED, "UnKnow Error"));
|
|
342
|
+
}
|
|
343
|
+
else
|
|
344
|
+
{
|
|
345
|
+
// 将 TokenData 转化为 AccessToken
|
|
346
|
+
AccessToken accessToken = new AccessToken
|
|
347
|
+
{
|
|
348
|
+
kid = tokenData.Kid,
|
|
349
|
+
tokenType = tokenData.TokenType,
|
|
350
|
+
macKey = tokenData.MacKey,
|
|
351
|
+
macAlgorithm = tokenData.MacAlgorithm,
|
|
352
|
+
scopeSet = tokenData.Scopes
|
|
353
|
+
};
|
|
354
|
+
tcs.TrySetResult(accessToken);
|
|
355
|
+
}
|
|
356
|
+
},
|
|
357
|
+
OnError = (e, loginType) =>
|
|
358
|
+
{
|
|
359
|
+
tcs.TrySetException(e);
|
|
360
|
+
},
|
|
361
|
+
OnClose = () =>
|
|
362
|
+
{
|
|
363
|
+
tcs.TrySetException(
|
|
364
|
+
new TapException((int)TapErrorCode.ERROR_CODE_LOGIN_CANCEL, "Login Cancel"));
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
TapSDK.UI.UIManager.Instance.OpenUI<LoginPanelController>("Prefabs/TapLogin/LoginPanel", openParams);
|
|
368
|
+
return tcs.Task;
|
|
369
|
+
}
|
|
158
370
|
}
|
|
159
371
|
|
|
160
372
|
public void Logout()
|
|
@@ -168,18 +380,65 @@ namespace TapSDK.Login.Internal
|
|
|
168
380
|
tcs.TrySetResult(AccountManager.Instance.Account);
|
|
169
381
|
return tcs.Task;
|
|
170
382
|
}
|
|
171
|
-
|
|
172
|
-
|
|
383
|
+
|
|
384
|
+
/// <summary>
|
|
385
|
+
/// 注册启动器检查完成事件,内部处理本地缓存与启动器用户信息的一致性问题
|
|
386
|
+
/// </summary>
|
|
387
|
+
private void RegisterListenerForTapClientCheck()
|
|
388
|
+
{
|
|
389
|
+
EventManager.AddListener(EventManager.IsLaunchedFromTapTapPCFinished, (openId) =>
|
|
390
|
+
{
|
|
391
|
+
TapLogger.Debug("receive IsLaunchedFromTapTapPCFinished event");
|
|
392
|
+
if (openId is string userId && !string.IsNullOrEmpty(userId))
|
|
393
|
+
{
|
|
394
|
+
CheckLoginStateWithTapClient(userId);
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/// <summary>
|
|
400
|
+
/// 校验缓存中的用户信息是否与 Tap 启动器中的一致, 不一致时清空本地缓存
|
|
401
|
+
/// 本地无用户信息时,默认为与启动器一致
|
|
402
|
+
/// </summary>
|
|
403
|
+
/// <param name="openId"></param>
|
|
404
|
+
private async void CheckLoginStateWithTapClient(string openId)
|
|
405
|
+
{
|
|
406
|
+
TapTapAccount account = await GetCurrentAccount();
|
|
407
|
+
if (account != null && account.openId != null)
|
|
408
|
+
{
|
|
409
|
+
if (account.openId != openId)
|
|
410
|
+
{
|
|
411
|
+
isCacheUserSameWithTapClient = false;
|
|
412
|
+
TapLogger.Debug("receive IsLaunchedFromTapTapPCFinished event and not same");
|
|
413
|
+
Logout();
|
|
414
|
+
}
|
|
415
|
+
else
|
|
416
|
+
{
|
|
417
|
+
isCacheUserSameWithTapClient = true;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
else
|
|
421
|
+
{
|
|
422
|
+
isCacheUserSameWithTapClient = true;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
private async Task CheckAndRefreshToken()
|
|
426
|
+
{
|
|
173
427
|
try
|
|
174
428
|
{
|
|
175
429
|
AccessToken accessToken = AccountManager.Instance.Account?.accessToken;
|
|
176
|
-
if(accessToken != null)
|
|
430
|
+
if (accessToken != null)
|
|
431
|
+
{
|
|
177
432
|
TokenData tokenData = null;
|
|
178
|
-
try
|
|
179
|
-
|
|
180
|
-
|
|
433
|
+
try
|
|
434
|
+
{
|
|
435
|
+
tokenData = await LoginService.RefreshToken(TapTapSdk.ClientId, accessToken.kid);
|
|
436
|
+
}
|
|
437
|
+
catch (TapHttpServerException e)
|
|
438
|
+
{
|
|
181
439
|
//清除本地缓存
|
|
182
|
-
if(e.ErrorData.Code < 0
|
|
440
|
+
if (e.ErrorData.Code < 0)
|
|
441
|
+
{
|
|
183
442
|
Logout();
|
|
184
443
|
}
|
|
185
444
|
return;
|
|
@@ -189,7 +448,8 @@ namespace TapSDK.Login.Internal
|
|
|
189
448
|
{
|
|
190
449
|
return;
|
|
191
450
|
}
|
|
192
|
-
AccessToken refreshToken = new AccessToken
|
|
451
|
+
AccessToken refreshToken = new AccessToken
|
|
452
|
+
{
|
|
193
453
|
kid = tokenData.Kid,
|
|
194
454
|
tokenType = tokenData.TokenType,
|
|
195
455
|
macKey = tokenData.MacKey,
|
|
@@ -197,14 +457,16 @@ namespace TapSDK.Login.Internal
|
|
|
197
457
|
scopeSet = tokenData.Scopes
|
|
198
458
|
};
|
|
199
459
|
ProfileData profileData = await LoginService.GetProfile(TapTapSdk.ClientId, refreshToken);
|
|
200
|
-
if (profileData != null)
|
|
460
|
+
if (profileData != null && isCacheUserSameWithTapClient)
|
|
201
461
|
{
|
|
202
462
|
AccountManager.Instance.Account = new TapTapAccount(
|
|
203
463
|
refreshToken, profileData.OpenId, profileData.UnionId, profileData.Name, profileData.Avatar,
|
|
204
464
|
profileData.Email);
|
|
205
465
|
}
|
|
206
466
|
}
|
|
207
|
-
}
|
|
467
|
+
}
|
|
468
|
+
catch (Exception e)
|
|
469
|
+
{
|
|
208
470
|
Debug.Log("refresh TapToken fail reason : " + e.Message + "\n stack = " + e.StackTrace);
|
|
209
471
|
}
|
|
210
472
|
}
|
|
@@ -8,6 +8,7 @@ using TapSDK.Core.Internal.Utils;
|
|
|
8
8
|
using UnityEngine.EventSystems;
|
|
9
9
|
using TapSDK.Core.Internal.Log;
|
|
10
10
|
using TapSDK.Core.Standalone.Internal.Http;
|
|
11
|
+
using TapSDK.Login.Standalone.Internal;
|
|
11
12
|
|
|
12
13
|
namespace TapSDK.Login.Internal {
|
|
13
14
|
public class QRCodeController {
|
|
@@ -111,7 +112,7 @@ namespace TapSDK.Login.Internal {
|
|
|
111
112
|
try {
|
|
112
113
|
TokenData tokenData = await LoginService.RequestScanQRCodeResult(clientId, qrcodeData.DeviceCode);
|
|
113
114
|
TapLog.Log("Login , QRCodeController Success");
|
|
114
|
-
onAuth.Invoke(tokenData,
|
|
115
|
+
onAuth.Invoke(tokenData, TapLoginTracker.LOGIN_TYPE_CODE);
|
|
115
116
|
return ;
|
|
116
117
|
} catch (TapHttpServerException e) {
|
|
117
118
|
string errorMsg = e.ErrorData?.Error ?? "";
|
|
@@ -6,6 +6,7 @@ using TapSDK.Login.Internal.Http;
|
|
|
6
6
|
using System.Collections.Specialized;
|
|
7
7
|
using TapSDK.Core.Internal.Utils;
|
|
8
8
|
using TapSDK.Core.Internal.Log;
|
|
9
|
+
using TapSDK.Login.Standalone.Internal;
|
|
9
10
|
|
|
10
11
|
namespace TapSDK.Login.Internal {
|
|
11
12
|
public class WebController {
|
|
@@ -95,7 +96,7 @@ namespace TapSDK.Login.Internal {
|
|
|
95
96
|
|
|
96
97
|
TokenData tokenData = await LoginService.Authorize(clientId, code);
|
|
97
98
|
TapLog.Log("Login , WebController Success");
|
|
98
|
-
onAuth.Invoke(tokenData,
|
|
99
|
+
onAuth.Invoke(tokenData, TapLoginTracker.LOGIN_TYPE_BROWSER);
|
|
99
100
|
|
|
100
101
|
return;
|
|
101
102
|
} catch (Exception) {
|
package/package.json
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"name": "com.taptap.sdk.login",
|
|
3
3
|
"displayName": "TapTapSDK Login",
|
|
4
4
|
"description": "TapTapSDK Login",
|
|
5
|
-
"version": "4.6.1
|
|
5
|
+
"version": "4.6.1",
|
|
6
6
|
"unity": "2019.4",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"com.taptap.sdk.core": "4.6.1
|
|
9
|
+
"com.taptap.sdk.core": "4.6.1"
|
|
10
10
|
}
|
|
11
11
|
}
|