por que HttpClient.GetAsync causa a abertura do link no navegador?
Suponha que tenhamos um aplicativo que deseja acessar a popular rede social russa VK e escrita em C # com a WinForms GUI. O VK usa uma abordagem semelhante ao OAuth2, portanto, precisamos abrir o navegador da Web com o URL de autorização vk oauth. Em seguida, assinamos o evento OnNavigated do webBrowser e aguardamos até que o URL não seja igual a algum URL predefinido com o token de acesso na string de consulta. A partir de agora, podemos chamar métodos vk usando o token de acesso recebido, mas algumas coisas estranhas acontecem aqui: quando tento invocar alguns métodos vk com HttpClient.GetAsync (methodUri), tudo corre conforme o planejado, exceto para abrir o link do navegador de autorização no navegador do sistema. O URL de autorização do cliente da vk parecehttps://oauth.vk.com/authorize?client_id={clientId}&scope={scope}&redirect_uri=https://oauth.vk.com/blank.html&display={displayType}&response_type=token
, URL com accessToken recebido parecehttps://oauth.vk.com/blank.html#access_token={accessToken}&expires_in={expiresIn}&user_id={userId}
, observe o sinal numérico no ponto de interrogação.
código na forma principal:
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);
código da classe 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);
}
}
Código ClientAuthenticator.Authenticate:
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;
}
depois de sair (usando o depurador)var response = await httpClient.GetAsync(request);
linha do formulário principal, o navegador do meu sistema abre um link comohttps://oauth.vk.com/blank.html#access_token={accessToken}&expires_in={expiresIn}&user_id={userId} - #access_token={accessToken}&expires_in={expiresIn}&user_id={userId}
com os recentes valores accessToken, expiresIn e userId. Sim com... - #access_token=....
no URL. Não tenho idéia do por que isso pode acontecer, mas estou preocupado com o sinal numérico.
adição importante: isso só acontece se o navegador da Web não tiver informações sobre uma sessão ou se tiver expirado, ou seja, eu tenho que inserir nome de usuário e senha no formulário de login da vk. se os cookies contiverem as informações necessárias e redirecionarem automaticamente para a página que contém o token em sua URL (com#
assine novamente), tudo funciona conforme o esperado