問題是我的previous question的延續。對問題的簡短解釋:我嘗試使用WinForms應用程序中的WebBrowser在vk.com上使用類似於OAuth2的方法來授權用戶,因此我需要在webBrowser中打開特定於應用程序的url,並且vk.com將重定向到授權頁面。授權後,vk.com重定向至https://oauth.vk.com/blank.html#access_token={accessToken}&expires_in={expiresIn}&user_id={userId}
,我可以將令牌與vk.com API一起使用。除了在授權後的不同時間在瀏覽器中打開的奇怪頁面(網址爲https://oauth.vk.com/blank.html#access_token={accessToken}&expires_in={expiresIn}&user_id={userId}%20-%20#access_token={accessToken}&expires_in={expiresIn}&user_id={userId}
)之外,一切都很好。 如果在處理WebBrowwser(AuthenticationForm - > authenticationBrowser_DocumentCompleted)控件後出現GC.WaitForPendingFinalizers(); GC.Collect();
,並且在另一種情況下打開,則我有點返工示例,現在該頁面在系統瀏覽器中不打開。處置WebBrowser控件導致在系統瀏覽器中打開新頁面
重要提示:該錯誤僅在必須填寫授權表單時出現,即Web瀏覽器不包含有效的會話數據。丟棄會話可以去設置 - >網頁的安全性 - >活動 - 見的歷史>關閉所有會話
的MainForm代碼:
public partial class Form1 : Form
{
private string _token;
private readonly Uri _redirectUri = new Uri("https://oauth.vk.com/blank.html");
private readonly Uri _request = new Uri("https://api.vk.com/method/users.get.xml?user_ids=1&fields=online");
private readonly Uri _authorizationUri =
new Uri("https://oauth.vk.com/authorize?client_id=3836576&scope=8&redirect_uri=https://oauth.vk.com/blank.html&display=page&response_type=token");
public Form1()
{
InitializeComponent();
}
private async void loginButton_Click(object sender, EventArgs e)
{
var authenticationForm = new AuthenticationForm();
authenticationForm.Show();
_token = await Authenticate(authenticationForm.GetToken);
authenticationForm.Close();
}
private async Task<string> Authenticate(Func<Uri, Uri, Task<string>> aunthenticationResultGetter)
{
var token = await aunthenticationResultGetter(_authorizationUri, _redirectUri);
//...
return token;
}
private async void doRequestButton_Click(object sender, EventArgs e)
{
//assume, we using token here
var httpClient = new HttpClient();
var response = await httpClient.GetAsync(_request);
var responseString = await response.Content.ReadAsStringAsync();
outputTextBox.AppendText(responseString);
}
}
authenticationForm代碼:
public partial class AuthenticationForm : Form
{
private readonly TaskCompletionSource<string> _tokenCompletitionSource = new TaskCompletionSource<string>();
private Uri _redirectUri;
private WebBrowser _authenticationBrowser;
public AuthenticationForm()
{
InitializeComponent();
}
public async Task<string> GetToken(Uri authUri, Uri redirectUri)
{
_redirectUri = redirectUri;
_authenticationBrowser = new WebBrowser
{
Dock = DockStyle.Fill,
Location = new System.Drawing.Point(0, 0),
MinimumSize = new System.Drawing.Size(20, 20),
Name = "authenticationBrowser",
ScriptErrorsSuppressed = true,
Size = new System.Drawing.Size(641, 353),
TabIndex = 0
};
_authenticationBrowser.DocumentCompleted += authenticationBrowser_DocumentCompleted;
_authenticationBrowser.Navigate(authUri);
Controls.Add(_authenticationBrowser);
var token = await _tokenCompletitionSource.Task;
return token;
}
private void authenticationBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (!(_redirectUri.IsBaseOf(e.Url) && _redirectUri.AbsolutePath.Equals(e.Url.AbsolutePath))) return;
_authenticationBrowser.Dispose();
//GC.WaitForPendingFinalizers();
//GC.Collect();
var token = e.Url.ToString().Split('=')[1].Split('&')[0];
_tokenCompletitionSource.SetResult(token);
}
}
您確定同一個'{accessToken}'令牌可以在不同的HTTP會話上使用嗎?服務器可以控制這個,而不是客戶端(除非您設法複製會話身份1:1,這不僅僅是複製cookie)。您需要使用Fiddler研究會話流量。 – Noseratio
@Noseratio,vk.com api文檔中的某個地方告訴記錄不綁定到http會話,它只綁定到ip。 –
我不認爲這只是IP地址。想想一個典型的網絡是在一個真實的IP後面進行NAT的。無論如何,**不要在自己的事件處理程序**中部署'_authenticationBrowser'。推遲''form.BeginInvoke'處置。 – Noseratio