为什么HttpClient.GetAsync会在浏览器中导致打开链接?

时间:2014-03-27 20:46:35

标签: c# winforms dotnet-httpclient vk

假设我们有一个应用程序想要访问流行的俄罗斯社交网络VK并使用WinForms GUI在C#上编写。 VK使用类似OAuth2的方法,因此我们需要使用vk oauth授权URL打开Web浏览器。然后我们订阅webBrowser的OnNavigated事件并等待,直到url与查询字符串中的访问令牌的某个预定义url不相等。 从现在开始,我们可以使用接收到的访问令牌调用vk方法,但是这里发生了一些奇怪的事情:当我尝试使用HttpClient.GetAsync(methodUri)调用一些vk方法时,一切都按计划进行,除了打开来自系统Web浏览器中的授权Web浏览器。 vk的客户端授权网址看起来像https://oauth.vk.com/authorize?client_id={clientId}&scope={scope}&redirect_uri=https://oauth.vk.com/blank.html&display={displayType}&response_type=token,已收到accessToken的网址看起来像https://oauth.vk.com/blank.html#access_token={accessToken}&expires_in={expiresIn}&user_id={userId},请在问号上记下数字符号。

主要形式的代码:

var authenticationForm = new AuthenticationForm();
authenticationForm.Show();
_authenticatedUser = await application.ClientAuthenticator.Authenticate(authenticationForm.GetToken);
authenticationForm.Close();

var httpClient = new HttpClient();
var request = "https://api.vk.com/method/users.get.xml?user_ids=1&fields=online";
var response = await httpClient.GetAsync(request);

authenticationForm类代码:

public partial class AuthenticationForm : Form
{
    private readonly TaskCompletionSource<VkAccessToken> _tokenCompletitionSource = new TaskCompletionSource<VkAccessToken>();
    private Uri _redirectUri;
    public AuthenticationForm()
    {
        InitializeComponent();
    }

    public async Task<IVkAccessToken> GetToken(Uri authUri, Uri redirectUri)
    {
        authenticationBrowser.Navigate(authUri);
        _redirectUri = redirectUri;
        var token = await _tokenCompletitionSource.Task;
        return token;
    }

    private async void authenticationBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
    {
        if (!(_redirectUri.IsBaseOf(e.Url) && _redirectUri.AbsolutePath.Equals(e.Url.AbsolutePath))) return;
        //working with e.Url to achieve token, userId and expiresIn, creating token variable based on them
        _tokenCompletitionSource.SetResult(token);
    }
}

ClientAuthenticator.Authenticate code:

public async Task<IVkAuthenticatedUser> Authenticate(Func<Uri, Uri, Task<IVkAuthenticatedUser>> aunthenticationResultGetter)
{
    var authorizationUri =
        new Uri("https://oauth.vk.com/authorize?client_id={clientId}&scope={scope}&redirect_uri=https://oauth.vk.com/blank.html&display=page&response_type=token");
    var token = await aunthenticationResultGetter(authorizationUri, _application.Settings.RedirectUri);
    //...
    return newUserBasedOnToken;
}

从主窗体退出(使用调试器)var response = await httpClient.GetAsync(request);行后,我的系统浏览器会打开https://oauth.vk.com/blank.html#access_token={accessToken}&expires_in={expiresIn}&user_id={userId} - #access_token={accessToken}&expires_in={expiresIn}&user_id={userId}之类的链接,其中包含最近的accessToken,expiresIn和userId值。是的,网址为... - #access_token=....。 我不知道为什么会发生这种情况,但我担心数字会出现。

重要的补充:只有当Web浏览器没有关于会话的信息或者它已过期时才会发生这种情况,也就是说,我必须在vk的登录表单中输入用户名和密码。如果cookie包含必要的信息,并且它会自动重定向到包含其中的令牌的页面(再次带有#符号),一切都按预期工作

0 个答案:

没有答案