$_SERVER vs. WSGI environ parameter - php

I'm designing a site. It is in a very early stage, and I have to make a decision whether or not to use a SingleSignOn service provided by the server. (it's a campus site, and more and more sites are using SSO here, so generally it's a good idea).
The target platform is most probably going to be django via mod_wsgi. However, any documentation provided with this service features php code. This method heavily relies on using custom $_SERVER['HTTPsomething'] variables. Unfortunately, right now I don't have access to this environment.
(How) can I access these custom variables in django? According the the WSGI documentation, the environ variable should contain as many as possible variables. Can I be sure that I can access them?

In Django, the server environment variables are provided as dictionary members of the META attribute on the request object - so in your view, you can always access them via request.META['foo'] where foo is the name of the variable.
An easy way to see what is available is to create a view containing assert False to trigger an error. As long as you're running with DEBUG=True, you'll see a nice error page containing lots of information about the server status, including a full list of all the request attributes.

To determine the set of variables passed in the raw WSGI environment, before Django does anything to them, put the following code in the WSGI script file in place of your Django stuff.
import StringIO
def application(environ, start_response):
headers = []
headers.append(('Content-type', 'text/plain'))
start_response('200 OK', headers)
input = environ['wsgi.input']
output = StringIO.StringIO()
keys = environ.keys()
keys.sort()
for key in keys:
print >> output, '%s: %s' % (key, repr(environ[key]))
print >> output
length = int(environ.get('CONTENT_LENGTH', '0'))
output.write(input.read(length))
return [output.getvalue()]
It will display back to the browser the set of key/value pairs.
Finding out how the SSO mechanism works is important. If it does the sensible thing, you will possibly find that it sets REMOTE_USER and possibly AUTH_TYPE variables. If REMOTE_USER is set it is an indicator that the user named in the variable has been authenticated by some higher level authentication mechanism in Apache. These variables would normally be set for HTTP Basic and Digest authentication, but to work with as many systems as possible, a SSO mechanism, should also use them.
If they are set, then there is a Django feature, described at:
http://docs.djangoproject.com/en/dev/howto/auth-remote-user/
which can then be used to have Django accept authentication done at a higher level.
Even if the SSO mechanism doesn't use REMOTE_USER, but instead uses custom headers, you can use a custom WSGI wrapper around the whole Django application to translate any custom headers to a suitable REMOTE_USER value which Django can then make use of.

Well, $_SERVER is PHP. You are likely to be able to access the same variables via WSGI as well, but to be sure you need to figure out exactly how the SSO works, so you know what creates these variables (probably Apache) and that you can access them.
Or, you can get yourself access and try it out. :)

Related

Static object that is accessible to all users like Application.cfc

I've done a fair bit of PHP over the years but I'm currently learning ColdFusion and have come across the Application.cfc file.
Basically this is a class that's created once (has an expire date). The class handles incoming users and can set session variables and static memory objects, such as queries. For example I can load site wide statistical data for one user in another thread from the Application.cfc. Something that would usually take a few seconds for each page would make the whole site quick and responsive.
Another example (just for clarification).
If I put an incremental variable that's set to 0 in OnApplicationStart this variable can be incremented with each user request (multiple users) or in OnSessionStart without the need to contact the SQL database since it's constantly in the server's memory under this application.
I was wondering if PHP has a similar file or object? Something that can be created once and used to store temporary variables?
The PHP runtime itself initializes the environment from scratch on every HTTP request, so it has no built-in mechanism to do this. Of course you can serialize anything into common storage and then read it back and deserialize on each request, but this is not the same as keeping it in-memory.
This type of functionality in PHP is achieved by outsourcing to other programs; memcached and APC are two of the most commonly used programs that offer such services, and both come with PHP extensions that simplify working with them.

Get unique worker/thread/process/request ID in PHP

In multi-threaded environments (like most web platforms) I often include some sort of thread ID to the logs of my apps. This enables me to tell exactly what log entry came from which request/thread, when there are multiple requests at once which are simultaneously writing to the same log.
In .NET/C#, this can be done by the formatters of log4net, which by default include the current thread's ManagedThreadId (a number) or Name (a given name). These properties uniquely identify a thread (see for example: How to log correct context with Threadpool threads using log4net?
In PHP, I have not found anything similar (I asked Google, PHP docs and SO). Does it exist?
Up until recently, I used apache_getenv("UNIQUE_ID"), and it worked perfectly with a crc32 or another hash function.
Nowadays I'm just using the following, in order to remove dependency on Apache and this mod.
$uniqueid = sprintf("%08x", abs(crc32($_SERVER['REMOTE_ADDR'] . $_SERVER['REQUEST_TIME'] . $_SERVER['REMOTE_PORT'])));
It's unique enough to understand which logs belong to which request. If you need more precision, you can use other hash functions.
Hope this helps.
zend_thread_id():
int zend_thread_id ( void )
This function returns a unique identifier for the current thread.
Although:
This function is only available if PHP has been built with ZTS (Zend Thread Safety) support and debug mode (--enable-debug).
You could also try yo call mysql_thread_id(), when you use that API for your database access (or mysqli::$thread_id when using mysqli).
PHP does not seem to have a function for this available, but your web server might be able to pass the identifier via environment variables. There is for example an Apache module called "mod_unique_id"[1] which generates a unique identifier for each request and stores it as an environment variables. If the variable is present, it should be visible via $_SERVER['unique_id'] [2]
"Pure PHP" solution could be to write a script that generates suitable random identifier, stores it via define("unique_id", val) and then use auto_prepend_file [3] option in php.ini to include this in every script that executes. This way the unique id would be created when the request starts processing and it would be available during the processing of the request.
[1] http://httpd.apache.org/docs/current/mod/mod_unique_id.html
[2] http://forums.devshed.com/php-development-5/server-unique-id-questions-163269.html
[3] http://www.php.net/manual/en/ini.core.php#ini.auto-prepend-file
I've seen getmypid() used for this purpose, but it seems to behave differently on different systems. In some cases the ID is unique to each request, but on others it's shared.
So, you're probably better of going with one of the other answers to ensure portability.
Assigning an ID in order to identify logged data from serving a request probably is as simple as creating a UUID version 4 (random) and writing it to every line of the log.
There even is software helping with that: ramsey/uuid, php-middleware/request-id
Adding it to every line of logging is easy when using log4php by putting the UUID to the LoggerMDC data and using an appropriate LogFormatter. With PSR-3 loggers, it might be a bit more complicated, YMMV.
A randomly created UUID will be suitable to identify one single request, and by using that UUID in the HTTP headers of sub requests and in the response, it will even be possible to trace one request across multiple systems and platforms inside the server farm. However, putting it as a header is not the task of any of the packages I mentioned.

Pass username & password from PHP to Apache

I have a loginform where users can login with two different accounts - one is a SolarisLDAP account and the other is an Active Directory account.
When the user tries to log in I want to find out which account he uses (which is not the problem).
If he's using the SolarisLDAP account, the authentication is done in PHP.
But if it is an AD account it must be passed to Apache (because I have to use the mod_auth_kerb to authenticate against our AD).
I wonder if this is possible in any way. Could I just set $_SERVER['PHP_AUTH_USER'] and $_SERVER['PHP_AUTH_PW'], or $_SERVER['REMOTE_USER'], and that's it?
Or would it be a possibility to kinda do it via the headers or a redirect?
Hope you understand what I'm trying to do..
Cheers
I wonder if this is possible in any way.
Unfortunately - no.
Also note that passing whatever variables from PHP to Apache makes no sense in that context.
It is not PHP but browser you want to authenticate with Apache, and, obviously, you have no control of.
This depends on which environment variables apache does set for the request. Do a
var_dump($_SERVER);
to get a list of all available ones. Go through that list and find out which ones are related to the authentication. It's probably something non-standard, this is a general list: http://php.net/_SERVER, compare it with your var_dump output.
Also this might depend on which Server-API (SAPI) you're using with PHPDocs.

Pass login information from Apache/PHP to Tomcat/GWT

We are planning to deploy our GWT module as explained in
http://code.google.com/webtoolkit/doc/1.6/DevGuideServerCommunication.html#DevGuideRPCDeployment
under the section "Using Tomcat with Apache HTTPD and a proxy"
Basically, we configured Apache/PHP server to pass on the requests to a Tomcat/GWT server that match a part of the URL. That worked as expected.
Now we would like to pass the information of the currently logged in user from Apache/PHP to the GWT module.
My initial idea was to load the GWT module from a PHP page (by including it's nocache.js) and include a login token with it which the GWT module can read.
But I am not sure if it is safe to read a DOM value and consider that as a login token.
Any suggestions for what would be the best way to do it?
Thank you.
IMHO it is definitifly the best idea to use a login-token, that is passed from apache/php to your gwt project. To pass this token, you have three possibilities:
First one: You can pass your token using a cookie. Write your token into a cookie and read it again in your GWT-context:
import com.google.gwt.user.client.Cookies;
Collection<String> cookies = Cookies.getCookieNames();
An example on dealing with cookies from GWT you can find in the GWT-Showcase.
Second one: Instead of writing your token to a cookie, you can pass it with a HTTP GET and read this again within your GWT-context:
// returns whole query string
public static String getQueryString() {
return Window.Location.getQueryString();
}
// returns specific parameter
public static String getQueryString(String name) {
return Window.Location.getParameter(name);
}
This method is -IMHO- that one you should never ever choose!
Third one: Instead of a HTTP GET you can also use a HTTP POST. The HTTP POST is send to the server. So you have to handle the request on your server-side with a simple servlet. This can be implemented as singelton and so be readable from your GWT-server-context. This method is a bit complex and brings a lot of work, since you then have to pass your information back to the GWT-client-context.
Which version is the best for you, depends on the details of your project. Usually I would say, that the Cookie-Version is the best.

How to pass parameters with hash in PHP

Recently when i saw google results page, the query and other parameters where passed with # (hash) instead of the usual "?"
Also, in facebook i saw the same thing. This was quite interesting and after a simple search with google, i found the results related to perl and Ruby but no result with PHP.
Is it possible to pass parameters with # in PHP instead of "?" or is this possible only with perl/Ruby. This will be useful and search engines will not parse the parameters in the URLs.
Any ideas will be helpful to me.
Traditionally, the # told the browser to automatically scroll to a particular point in the page, which was (and still is) often used to implement links from one part of a page (e.g. a table of contents) to another (e.g. a section heading).
However, it also has the effect of causing the URL containing the # to be recorded in the history, even if it's identical to the previous URL except for the # and what follows it. (In other words, the user is still on the same page.) This means that the back button can be used to get back to the state that you were previously in, even if that state-change doesn't correspond to a page-load.
Modern AJAX applications therefore often use it to signify that something has happened that the user might want to "go back" from.
Nope, it is not possible.
What have you seen is just a decoration, to reflect an AJAX call in the address bar.
No matter what language you choose - all of them sits on the server side and communicate with browser using HTTP protocol. And no anchor allowed in HTTP requests. That's completely client side thing
You are running into confusion in your search results because the term hash is overloaded, as is the concept of parameter passing.
You are seeing references to the concept of passing values in a hash beacause an associative array is called a hash in some languages (which is short for a hash table).
The # character is also confusingly named. It is called, "hash", "pound", "number" and "octothorpe". Since I grew up in the US, I call it a "pound sign" in my head, which is likely annoying to users of more British English, and is no less fraught with potential for confusion (consider "£").
Passing function arguments in a hash in Perl is a nice way to get named arguments for a routine. PHP has positional arguments only, but using an Array works nicely there.
Many web libraries use a hash/associative array type structure for form values. Keys are typically the field id, and values are the field values.
In a URI the # denotes the start of the fragment specifier. It identifies a part of the page that the URI points to. It is generally not used to pass request information from the client back to the server.
there probably is some server rewriting or so.
Example with apache server, you can handle some uri like
http://www.mysite.com#something
and rewrite it as
http://www.mysite.com/perl/script.pl?data=something
and so process it as a simple GET query to your script.pl
This is all server-side processing, un-visible to the client

Categories