We have our current website in PHP. We are currently upgrading it in Node. We will upgrade it step by step so we'll have some pages in PHP and some other in Node.
Problem is, when users will connect we have to make sure they have a session in both PHP and Node, so they won't have to connect twice.
In PHP we create a PHPSESSID cookie and we store all the data in a session file in /tmp.
In Node we use a JWT token.
What i am trying to achieve right now is: when and user connects with a page that runs on Node, it has to create a PHPSESSID cookie and the session file, so when he will navigate to another page that runs on PHP he will still be connected.
The PHP website and the Node API have the same domain but run on a different port.
Right now what my code does is:
I call the signIn function from the Node API
It creates the JWT token and the user is connected properly in Node
I call the PHP website like this: http://www.mysite.local/ajax/login?user=user&pass=pwd
It creates the session file correctly
It creates the PHPSESSID cookie
But when i check the cookies of my domain, the PHPSESSID doesn't appear. But it does after i create it and print $_COOKIE in PHP.
And because of that PHP can't find any PHPSESSID cookie and can't access the session file.
I'm using Node with GraphQL and Apollo, and PHP with Zend Framework 1.12
Here is how i call PHP with Node:
const url = `http://www.mysite.local/ajax/login?email=${data.email}&password=${data.password}`
const headers = {
Referer: 'http://www.mysite.local/auth'
}
await fetch(url, { method: 'GET', headers: headers })
The sessions in PHP are managed by Zend
I'm testing on Firefox.
HTTP cookies work like this:
The client sends an HTTP request to the server
The server responds with an HTTP response which includes a Set-Cookie header
The client then stores the cookie
Later on, the client sends another HTTP request to the same server. Since it has a stored cookie, the cookie is including in the request headers.
Browsers will, in general, automatically store cookies. (There are some edge cases, like Ajax requests only handling cookies in cross-origin requests if withCredentials is enabled).
Server-side code will, in general, not automatically store cookies. When dealing with server-side code you usually need to explicitly deal with cookies, usually by configuring a cookie jar library (e.g. fetch-cookie).
You are making an HTTP request from the browser to Node.js.
Node.js is making an HTTP request to PHP.
PHP is responding with a cookie (I assume)
Node.js is ignoring the cookie
Node.js is making an HTTP response to the browser
The browser gets the HTTP response (with no Set-Cookie header in it).
At no point does Node.js either read the cookie from the request it made to PHP or copy that cookie in the response it makes to the browser.
That is what you need to do.
(And then you'll need to continue to proxy requests to the PHP through the Node.js because the cookie stored in the browser would be associated with the Node.js server).
Related
I'm learning about Laravel passport package and creating a SPA using Vue.js to test it, I'm wondering about saving the Token in the client browser, If I saved it on local storage it would be accessible from Javascript and anyone run js on the browser would be able to read it !
My questions are; What is the solution for this situation ?
If I saved the token in the cookies It would be accessible too, and I read about httpOnly cookies, so How can I set the cookies to save the token from the response from the API if it's not accessible by Javascript ?
Is there a way to save the cookies from the API ?
I hope I can find answers for my Questions.
Well, there are a couple of things to understand here.
HTTP only cookie
First, HTTP cookies are set by the server using set-cookie header. In this case, you as a developer need not do anything. The browser will automatically set it for you and will send back to the server on each Ajax or non-ajax requests. It will send the cookie as long as it is not expired.
LocalStorage
When using LocalStorage for storing the token, any JavaScript code can read it (known as XSS attack if misused). But, the key thing to understand here is that other domain's JavaScript code cannot read the LocalStorage. The scope is restricted to your own site. Other website's JS cannot read it. So, if you are not using any external dependency or compromised CDN, you are safe.
Cross-site cookie
No. It is impossible to set a cross-domain cookie under any circumstances. Only other domain's server can set a cookie for itself (Unless you have some backend mechanism like Gmail + Youtube to share session). However, in case of a subdomain, the following things are allowed:
Parent domain can set a cookie for any child domain. That is example.com can set a cookie for *.example.com.
Child domain can set a cookie for the parent domain. That is xyz.example.com can set a cookie for example.com.
Of course, the rules are more complicated than that. This article should help you understand further.
I have my Ionic/angular 2 app that is running on localhost:8000 The app will run eventually on browser platform. The app is calling a RESTFull api hosted on my local machine on https://adawy/api, where adawy is my hostname and defined in both hosts file and in apache virtual hosts. The server side is Slim 3.
The API upon authentication is returning a JWT to be used with all requests.
My goal is to protect the token from cross site request forgery and cross site scripting. Saving the token in a javascript variable or in any form of local storage would make the JWT accessible from javascript.
I found that the best way is to return the JWT to as an HTTPOnly cookie. So it won't be accessible from javascript and would be sent only by the browser with any upcoming requests to adawy domain.
I had returned the token successfully as a cookie but the problem is that the cookie is not sent with any next XHR requests.
Also, I cannot see the cookie in the Cookies section in Devtools.
I know that angular can support in such matter by looking for XSRF-TOKEN cookie.
It is not working either, as you can see I set the name of the cookie to XSRF-TOKEN but yet, with any other request, this cookie is not sent.
I wonder how this would be secured as if angular has access to this cookie, so would any other script?
Here is the next request, with no cookie sent. Please ignore the header Authorization as my angular code is setting it directly.
In my angular app, I am setting the withCredentials: true option while making the last get request.
Update
I had used adawy.com and I still have the same issue.
The first response attempts to set the cookie explicitly on a top level domain Domain=.adawy; (see the Set-Cookie header) which is not allowed. Try setting it without the domain if you can and see if that works. Alternatively, try using a hostname that has a tld on it.
I am working on a service that sits between a client and an API. A client user does API requests via my service. The API requires several user cookies to be set to authenticate the user and allow requests. The client cannot store cookies, so I am storing all the cookies on AWS EFS. The service is written in PHP and API requests are done using cURL. Cookie handling is done using cURL's CURLOPT_COOKIEFILE and CURLOPT_COOKIEJAR.
The problem is that sometimes the cookie file gets overwritten instead of appended to or updated, leading to API requests failing. I am still trying to find the cause of this, but I am considering saving the cookies to the database instead of in a file. Obviously this will lead to an increased database load, but I cannot think of any other disadvantages. Are there any?
Ok I guess this question may be similar to other in the "remote cookies" kind, but I'm not sure that other answers I've read are applied to my case anyway, so here we go.
I have two applications, a client and a server. The server "has" (I know they're actually stored client-side) a cookie and a page which uses it to print out a computed data based on the cookie.
If I access the server page directly, the cookie is taken into account and the data is output correctly.
If I call the same server page from the client via a file_get_contents() the cookie on the server page doesn't get read, and I get an answer computed with an empty cookie.
How to make the server read its own cookies when answering a similar request? Is cURL the only option?
You need to:
Make a request that gets a Set-Cookie header in the response (assuming the cookies are HTTP cookies and not JS cookies)
Store the cookies
Include the cookies in the HTTP request to the page that displays them
cURL is probably the sanest way to go about dealing with being an HTTP client in PHP when you need to pay attention to the headers. Another question gives some guidance about how to go about doing that.
Note that there is no way to send the cookies that the browser accessing your PHP script would sent to the remote server. They are a secret that belong to the browser and that server and will not be shared with your server.
I am doing authentication for a web service in php. When a user authenticates a session is generated. Eventually this session expires and the user needs to authenticate again. The authentication information is sent in the http headers.
But it seems that sometimes the variable $_SERVER (or apache_request_headers()) return some headers that are not being sent by the client in the current request (they were sent in previous requests). For instance sometimes I get the variable $_SERVER['HTTP_RESPONSE'] filled with information from previous requests.
Is it normal for $_SERVER or apache_request_headers() to 'persist' across requests?
It depends on whether or not you're using a browser to access the script.
Your 'persistent' headers are probably due to browser caching, but even then I'm not entirely sure what is happening. I've tried running a few tests using Fiddler, but couldn't replicate the problem.
Maybe try clearing your cache, as different headers might have been stored from previous versions of the script.
But, I would definitely avoid sending authentication params in the headers. Unless you're using HTTPS, they're liable to be sniffed and stolen. Why are you using headers?
$_SERVER contains information about the server, it doesn't necessarily contain any request/response information, it's persistent across the server life-time (eg, the SERVER_NAME will persist, but has nothing to do with the REQUEST/RESPONSE)
apache_request_headers() contains an array of headers which were sent, those may or may not include any cookie and session information - they are dependent on the client which you're using to access the server.
the only thing which persists across requests, it $_SESSION, because everytime you're accessing the $_SESSION superglobal, it fetches the session information which was saved on the file system (basic PHP implementation), some frameworks persist the session in the database (such as Yii).
I'm assuming you want to create a request header based authentication, so what you need to actually do, is parse the request_headers, match those against a legal user credentials, and simply open_session(); and put a value in the session which will mark the user as authenticated, any subsequent check, will be made against the $_SESSION superglobal, or against some other-implementation of sessions.