When authorizing via the VKontakte API, the following URL is redirected:

http: // localhost: 58821 / Auth # access_token = 123456712345123451234512345 & expires_in = 0 & user_id = 1234567

Appeal to Request.Url.AbsolutePath , Request.Url.AbsoluteUri or Request.RawUrl gives only a link to the host. How can I get parameters from this URL? Upd. Probably the problem is that the address and get parameters are separated by the '#' symbol, and not the '?', So the parameters cannot be obtained. Is it possible to somehow get the whole line?

    5 answers 5

    You made a mistake when choosing the type of authorization - you need to use authorization intended not for mobile applications (client), but for sites (server).

    At the same time, it is necessary that your web server is accessible from the outside - if not by the domain, then at least by some kind of public ip. With localhost server authorization will not work.

    If you had client code, you could add System.Web assembly to your project and use code like this:

     var uri = new Uri("http://localhost:58821/Auth#access_token=123&expires_in=0&user_id=456"); var fragment = uri.Fragment.TrimStart('#'); // access_token=123&expires_in=0&user_id=456 var access_token = HttpUtility.ParseQueryString(fragment).Get("access_token"); // 123 

    However, you have a site on ASP.NET, and you will not receive a fragment (part of Uri starting with '#') from the server code in any way - it is not transmitted by the client.

    In your case, authorization for mobile devices cannot be used. More precisely, of course, you can ask the user for their real username / password, transfer them instead of the user, authorize their application, and save the token - but it smacks badly, and will surely cause mistrust among users.

    • Sergey, thanks for the explanation. Perhaps you can help with one more question: I need to perform a global search for posts on Facebook (the task is to find references to the company), the api "getHint" method works well for this, but it is not available for sites. Perhaps tell me the way out or replacement of this method? Thank you in advance. - Uran_90
    • @ Uran_90, for this task, newsfeed.search is more likely to be suitable - a method that does not require any authorization, which actually finds mention of the specified words in VKontakte posts. And search.getHint is primarily intended for displaying a “search prompt” - it searches not by posts, but by names and descriptions of groups, public pages, and users - while people and groups to which the current user is signed are always displayed first, regardless low relevance. - Sergey Rufanov
    • Thanks again for the tip, Sergey - Uran_90

    I killed two days to solve this problem for myself, finally decided, though I have a java server, but I think it will not be a particularly big problem to understand. server is running on localhost!

    So in steps: 1 - in vk on the page with the settings of the application you need to enable openAPI and in the settings of the hosts register localhost and the page that will be redirected from the https://oauth.vk.com/authorize method in the redirect_uri parameter in me it looks like this application setup

    2 - you need to use server authorization and not client: a link to vk.api ie first you need to get the code

     getCode { @Override public String getExactMethod() { return "https://oauth.vk.com/authorize?" + "client_id=" + AppProperty.properties.getProperty("vk.client.id") + "&scope=market" + "&display=popup" + "&redirect_uri=" + AppProperty.properties.getProperty("vk.client.uri.local") + "&response_type=code" + "&v=5.60"; } } 

    Thus, in the response, the code will come as the default get parameter. I get it and process it in the filter by assigning a class constant

    3 - having received the code, you can send a GET request to https://oauth.vk.com/access_token using HttpClient; for me it looks like this: forming a request

     getAccessToken { @Override public String getExactMethod() { return "https://oauth.vk.com/access_token?" + "client_id=" + AppProperty.properties.getProperty("vk.client.id") + "&client_secret=" + AppProperty.properties.getProperty("vk.client.secure.key") + "&redirect_uri=" + AppProperty.properties.getProperty("vk.client.uri.local") + "&code=" + code; } } 

    where code is already assigned from the last stage, then I send the request itself:

     public Object sendGetRequest(SimpleRequest request) { HttpGet postRequest = new HttpGet(request.getUri()); JSONObject vkApiJsonResponse = null; try (CloseableHttpClient httpClient = HttpClientBuilder.create().build(); CloseableHttpResponse response = httpClient.execute(postRequest)){ String json_string = EntityUtils.toString(response.getEntity()); vkApiJsonResponse = new JSONObject(json_string); } catch (Exception e) { FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Ошибка.", e.getMessage())); } return vkApiJsonResponse; } 

    which returns a JSON object that contains the token, its lifetime and user_id, here's an example of the return value from my debug

    enter image description here

    4 - profit! :) I hope it will save someone or a couple of sleepless nights / long days. All good!

      You can use QueryString to get parameters

       if ( Request.QueryString.AllKeys.Contains("user_id") ) { var id = Request.QueryString["user_id"]; } 
      • Probably the problem is that the address and get parameters are separated by the '#' character, not the '?', So the Request.QueryString array is empty - Uran_90

      ASP.NET has a Request object that contains the data associated with the current request. In particular, the query parameters too. The main way to get them is to use the QueryString property, which is a collection of keys and values. You can also use a class Request indexer like this:

       Request["myparam"] 

      but in the case of the indexer, the data is searched for by the key not only among the url parameters, but also among the form parameters, cookies and server variables.

      • Probably the problem is that the address and get parameters are separated by a '#', and not a '?', So Request ["access_token"] gives null. - Uran_90

      The part of the request after # (anchor) may not be sent to the server. You can get access to the anchor on the client via javascript and send it, for example, to a server for processing.

      Javascript:

       var hash = window.location.hash.substring(1); 

      Jquery:

       var hash = $(location).attr('hash').substring(1); 
      • Hmm, what's the minus? - VladD
      • @VladD it is possible that someone was upset that the window.location.hash.substring(1) and $(location).attr('hash') variants produce different results. - Regent
      • And the use of jQuery in this case does not give any advantages. - Regent
      • And you have here strictly - pavelip