Basically I'm just messing around with a library which should work with some API (for studying purpose). So, in order to conform OAuth protocol I need to authorize using some sort of web view and get access token. AT is passed as GET parameter after redirection. As a novice in Qt, I have no idea how to track web view state and fetch essential data.
Practically I have an auth procedure that takes a callback, which has to return access token afterwards, as a parameter.
vk_api::auth<>("123456", vk_api::scopes::friends, [this](const std::string& contents) -> std::string {
this->ui->m_webview->setHtml(QString(contents.c_str()));
...
});
Also, I do not want to block UI while calling it.
Some options you have:
Use the new Qt Network Authorization library.
If you want to do it yourself, the usual way is to let the service redirect to a localhost port, which you listen to. See QTcpServer and Network Programming with Qt for that.
Qt WebKit is deprecated, use QWebEngineView instead. You can intercept requests and look for the authorization token using a QWebEngineUrlRequestInterceptor
You can intercept requests made from Qt WebKit and look for the authorization by using a custom QNetworkAccessManager.
Related
I'm trying to apply server side authentication in a similar way to how getServerSideProps() works in the older /pages approach to nextjs.
However with this approach getServerSideProps takes a context parameter which contains both the req and res from the server. Which means we could attach headers to the response.
Is this context (or parts) accessible in the new Server Components within nextjs 13?
I know I can access cookies and headers for the request using the next/cookies and next/headers - is there a way to access the response? Current cookies.set() function doesn't work (throws an error), do I need have to wait for this to be implemented?
So I'm using react native websockets but cannot figure out how i can include cookies in websockets, any suggestions?
At the moment there is no automatic way to do it. There is a third (undocumented) parameter for the WebSocket constructor to pass custom HTTP headers to the connect request.
WebSocket(url, '', {Cookie: 'key=value'});
This works on iOS, I haven't tested it on Android but the WebSocket implementation looks like it is supported there as well.
If you just need to pass a session id or auth token, it's probably easier to pass it as a GET param in the url. Relying on undocumented behavior in a rapidly changing framework can be dangerous.
If you look at the WebSocket declaration, you can see that the header keys should be strings.
This works for me:
var headers = {};
headers["cookie"] = `cookieName=${cookieValue}`;
const ws = new WebSocket(`wss://www.somesite.com/socket`, null, {
headers
});
not this:
{
headers: {
cookie: `cookieName=${cookieValue}`
}
}
As of React Native 0.38, this should happen automatically on Android.
There's currently an open PR for making it work automatically on iOS as well, but at the moment it seems there's still some work left there around testing.
In the meanwhile, you could follow the "manual approach" proposed here:
Manual approach is to retrieve the cookie through a cookie manager plugin and pass it as headers to web socket.
(Once you have the cookie from the manager, the way to pass it to the websocket is, as mentioned previously, to use the undocumented 3rd parameter of WebSocket.)
I'm trying to write a simple application that will launch a browser and send it to a URL based on a user's input.
QDesktopServices::openUrl(QUrl(url));
However, I'd like to pass variables along with whatever URL they submit using POST.
For GET, all I'd need to do is simply embed the values into the URL string, but how would I go about adding POST variables?.
Thanks.
QDesktopServices wasn't designed for this, I'd suggest doing your HTTP POST using QNetworkAccessManager::post instead.
You can then possibly take some information from the HTTP response to open the desktop browser if this is necessary.
From the official documentation:
bool QDesktopServices::openUrl(const QUrl & url) [static]
Opens the given url in the appropriate Web browser for the user's desktop environment, and returns true if successful; otherwise returns false.
If the URL is a reference to a local file (i.e., the URL scheme is "file") then it will be opened with a suitable application instead of a Web browser.
The short answer is that it was not meant to be a network managet. For that purpose, one could already use the QNetworkAccessManager. It was just a convenient way to add support for opening up an URL as that would require quite a bit of work otherwise. There were no further plans to it to replicate QtNetwork more closely.
Thereby, I would suggest to use something like this to achieve working with post methods given your url:
QUrlQuery urlQuery;
urlQuery.addQueryItem("param1", "value1");
urlQuery.addQueryItem("param2", "value2");
QUrl url = QUrl("http://foo.com");
QNetworkRequest networkRequest(url);
networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
networkManager->post(networkRequest, urlQuery.toString(QUrl::FullyEncoded).toUtf8());
If you have no issue with maintaining an external web service, you could set up a GET-to-POST redirection service (since QDesktopService::openUrl can pass url query strings to browsers without issue). Two things to keep in mind when going this route are to a) properly validate the requests the service recieves against some sort of whitelist to avoid security issues that stem from open http redirection, and b) to consider URL length limitations of both the user's desktop browser and server handling the redirects.
If we ignore IE and edge, desktop web browsers seem capable of handling URLs 32k-bytes long or better (figure obtained from a quick web search, may be inaccurate). If you're also targeting older android phones, the length limit drops to 8k.
Another way is to use QWebView which doesn't suffer from the same flaws as QDesktopServices: https://doc.qt.io/archives/qt-5.5/qwebview.html#load-1 . The only issue with this is that it will require use of the webkitwidgets module which may or may not be an issue for you.
Side note: I'm also still trying to find a way deal with the QDesktopServices problem. If you found a better way to send a POST request through the user's default browser, please post it here so that others can benifit.
Cheers.
I'm using Dev-C++ and i'm looking for a mode to open(...or better...i need to load a browser intance in the background) the default browser (Example I.E.) and send a request to get the source code of the page I requested.
Can I do something like this in C++?
Thank you!
P.S. I need this for Windows
You seem to have imagined the wrong solution for your problem. If you want to get the HTML source for a web page, you don't need to somehow do it through the browser. You need to do whatever the browser does to get it.
When you enter an address into a browser, the browser sends a HTTP GET request to the server that hosts the resource you're requesting (often a web page) and the server sends a HTTP response back containing the resource content (often HTML) back.
You want to do the same in your application. You need to send a HTTP request to the server and read the response. A popular library for doing this is libcurl.
If you don't have to send a POST request (i.e. just a simple web request or with parameters passed on the URL (GET), then you could just use URLDownloadToFile().
If you don't want to use callbacks etc. and just download the file, you can call it rather simple:
URLDownloadToFile(0, "http://myserver/myfile", "C:\\mytempfile", 0, 0);
There are also a few other functions provided that will automatically push the downloaded data to a stream rather than a file.
It can't be done in pure C++. You should use native Windows library or other (like Qt Framework) and use it's capabilities of getting and parsing website. In Qt, you'd use QtWebkit.
edit: also if you want only the source code of a page, you can do this without using browser or their engines, you can use Winsock.
I’ve got a Web API that I’ve added [Authorize] attributes to, which means that the unit tests I had previously now fail due to them being unauthorised. Here’s a sample of a basic test along with an initialiser method:
[TestInitialize]
public void CreateServer() {
var config = new HttpConfiguration();
WebApiConfig.Configure(config); // Create the routes
var server = new HttpServer(config);
this.client = new HttpClient(server);
}
[TestMethod]
public void MyThings_GET_Returns_All_MyThings() {
var response = this.client.GetAsync("http://localhost/api/1.0/mythings").Result;
var mythings = response.Content.ReadAsAsync<IEnumerable<MyThing>>().Result;
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
Assert.AreEqual(4, mythings.Count());
}
What I’m wondering is if there’s any way that I can either make my test log in so that it passes the authorization filter, or if there’s any way that I can pass as ASPXAUTH cookie along with the HttpClient request? Or another way of passing authorization that I haven’t thought of?
Nothing I’ve tried seems to work and I’m struggling to find any helpful info anywhere.
Thanks in advance.
What does your Authorize attribute do when it performs the authorization check? There are quite a few options that come to mind:
Have the authorize filter support multiple means of getting the "authorization token" that it requires (e.g. through an HTTP header or a querystring parameter, etc)
Right after your test initialization, clear out the filter from the configuration (so that it is not called at all). If you choose to go this route then you may wish to pop in a new filter that sets any authorization values that might be used further along the pipeline
If you are using dependency injection, move the "authorization check" into some sort of IAuthorize location that can be updated in your configuration
I would also recommend using RestSharp for making queries to your endpoints as it does a very good job of specifying headers, parameters, etc.
I decided that the way I was going about the problem was fundamentally wrong. Using cookie-based authorisation with Web API is just not a good idea, so I’ve decided to get rid of the authorize attributes and perform API-Key-based authentication instead. This makes it easier to test as I can just pass the correct API key in the request, but also means that I’m not relying on cookies for authorisation.