// Step 2 in https://developer.twitter.com/en/docs/basics/authentication/overview/3-legged-oauth // Use this method when you passed a callback URL in `GetUserAuthenticationUrl()`. // Pass the callback that your app received from the earlier request's callback. public async UniTask AuthorizeUser(string callback) { // Check URL format if (!Uri.IsWellFormedUriString(callback, UriKind.Absolute)) { throw new Exception($"Malformed callback: {callback}"); } // Check presence of callback parameters var components = callback.Split('?'); if (components.Length < 2) { throw new Exception($"Invalid callback: {callback}"); } // Parse callback parameters var response = TWOAuth.ParseParameters(components[1]); var verifier = response["oauth_verifier"]; var token = response["oauth_token"]; // `oauth_token` must be the same as the request token // (otherwise this callback is coming back from a different request) if (token != _userRequestToken) { throw new Exception("Mismatched request token"); } // Try authorizing with the verifier if (!await AuthorizeUserWithVerifier(verifier)) { throw new Exception("Invalid verifier"); } }
// Step 3 in https://developer.twitter.com/en/docs/basics/authentication/overview/3-legged-oauth // Also use this method when you're using PIN-based OAuth (passed "oob" to `GetUserAuthenticationUrl()`). // Pass the user's PIN code to `oauthVerifier` parameter. public async UniTask <bool> AuthorizeUserWithVerifier(string verifier) { // Check if this client has actually requested a token earlier if (_userRequestToken == null || _userRequestTokenSecret == null) { throw new Exception("Request token/secret has not been granted"); } var query = new Dictionary <string, string> { { "oauth_verifier", verifier }, }; using (var req = UnityWebRequest.Post(UserAuthorizationEndPoint, query)) { var oauthHeader = TWOAuth.MakeHeader( oauthToken: _userRequestToken, oauthTokenSecret: _userRequestTokenSecret, consumerKey: _app.ConsumerKey, consumerSecret: _app.ConsumerSecret, httpMethod: req.method, endpointUrl: req.url, extraParams: query); req.SetRequestHeader("Authorization", oauthHeader); await req.SendWebRequest(); if (req.responseCode == 401) { return(false); } TWHttpException.ThrowIfError(req); // Parse OAuth parameters var response = TWOAuth.ParseParameters(req.downloadHandler.text); var token = response["oauth_token"]; var secret = response["oauth_token_secret"]; Debug.Assert(token != null); Debug.Assert(secret != null); // Save the granted access token to storage _storage.UserAccessToken = token; _storage.UserAccessTokenSecret = secret; return(true); } }
// Generate an OAuth header using the user token that must have been granted earlier async UniTask <string> MakeAuthHeaderAsUser(string httpMethod, string targetEndpoint, IDictionary <string, string> extraParams = null) { if (!_storage.UserTokenExists) { throw new Exception("Failed authorizing user request: User token not granted"); } await UniTask.SwitchToThreadPool(); var oauthHeader = TWOAuth.MakeHeader( oauthToken: _storage.UserAccessToken, oauthTokenSecret: _storage.UserAccessTokenSecret, consumerKey: _app.ConsumerKey, consumerSecret: _app.ConsumerSecret, httpMethod: httpMethod, endpointUrl: targetEndpoint, extraParams: extraParams); await UniTask.SwitchToMainThread(); return(oauthHeader); }
// Step 1 in https://developer.twitter.com/en/docs/basics/authentication/overview/3-legged-oauth // For callback URL syntax, see https://developer.twitter.com/en/docs/basics/apps/guides/callback-urls // To use PIN-based OAuth, pass "oob" to `callbackUrl` parameter. // Navigate user to Twitter on a web browser using the URL returned from this method. public async UniTask <string> GetUserAuthenticationUrl(string callbackUrl) { using (var req = UnityWebRequest.Post(UserAuthRequestEndpoint, "")) { var oauthHeader = TWOAuth.MakeHeader( oauthToken: _app.AccessToken, oauthTokenSecret: _app.AccessTokenSecret, consumerKey: _app.ConsumerKey, consumerSecret: _app.ConsumerSecret, httpMethod: req.method, endpointUrl: req.url, extraParams: new Dictionary <string, string> { { "oauth_callback", callbackUrl } }); req.SetRequestHeader("Authorization", oauthHeader); await req.SendWebRequest(); TWHttpException.ThrowIfError(req); var response = TWOAuth.ParseParameters(req.downloadHandler.text); if (response["oauth_callback_confirmed"] != "true") { throw new Exception("OAuth failed: oauth_callback_confirmed was not true"); } _userRequestToken = response["oauth_token"]; _userRequestTokenSecret = response["oauth_token_secret"]; Debug.Assert(_userRequestToken != null); Debug.Assert(_userRequestTokenSecret != null); return($"{UserAuthenticationEndpoint}?oauth_token={_userRequestToken}"); } }