"Curiosity is the very basis of education and if you tell me that curiosity killed the cat, I say only the cat died nobly." - Arnold Edinborough

I really enjoy how easy Laravel makes forms. Being able to pass in a model to Laravel and have it take care of everything is awesome. Sometimes I simply don’t want to make a whole model for my form data, though. If you are similarly lazy at times then there’s a simple way to still have your default form values based on previous input.

Simply create a StdClass object and store the input values in there.

$sorting = new StdClass;
$sorting->sort_by     = Input::get('sort_by', 'displayname');
$sorting->sort_order  = Input::get('sort_order', 'asc');
$sorting->sort_region = Input::get('sort_region', 'all');

Pass $sorting to your template and use it with Form::model() and you’re good to go.

For security reasons it’s fairly good practice to invalidate all log-in sessions when a users password is changed. This is especially useful when a users account has been compromised and they go to change or reset their password. Without log-in session invalidation the attacker will still be logged in and able to cause chaos.

Unfortunately Laravel does not provide this functionality out of the box. We actually have to go through quite a bit of trouble to make Laravel play ball here but it’s definitely worth it, so lets get to it!

Implementing this feature is a two step process.

  1. Track the session IDs of all logged in users.
  2. Invalidate the session data attached to those user sessions.

Part one is fairly simple and can be done in your own application code. The session ID is exposed through Session::getId() so simply add this to an array of session ids stored in a persistent cache. When When you want to invalidate the log-in sessions simply fetch this cached array. I will leave this part as an exercise to the reader.

Part two is where it gets tricky. The Laravel session providers themselves implement a very suitable destroy method that takes a session ID. However, unfortunately the Laravel session store does not expose this method but instead implements a migrate() method. This method does not take a session ID, but instead offers to destroy the current session. Invalidating the session of the user changing the password is all perfectly fine, but that still leaves our attacker logged in. In order to fix this we need to implement a custom session store that properly exposes the destroy() method of the individual session providers.

The following code is done in Laravel 4.2. Version 5 has quite a few changes so this might be significantly different. If anyone uses Laravel 5 please let me know if this applies there as well.

In order to implement this we need to backtrack to where Laravel actually loads session classes. This is defined in your app.php providers array as ‘Illuminate\Session\SessionServiceProvider’. The SessionServiceProvider registers a SessionManager which then creates the Store class we’re looking to extend. This means we need to provide our own version of these 3 classes and then modify app.php to load our own SessionServiceProvider class.

Read More

As of Laravel 5.0 it’s still not possible to set the remember me cookie with a secure flag. This is slightly weird as there is a configuration option for secure session cookies. Fortunately modifying Laravel to set a secure log-in cookie is not too difficult – all we need to do is provide a custom Guard class for the Auth driver which overrides the setRecaller() method.

This code is done against Laravel 4.2, I’m not sure how simple it is to adapt to 5.0 as I have not had a chance to work with that yet. Feel free to let me know in a comment.

<?php 
/*  
 * Custom guard class that sets a secure log-in cookie.
 */ 
class SecureGuard extends \Illuminate\Auth\Guard
{
	/**
	 * Create a secure remember me cookie for a given ID.
	 *
	 * @param  string  $value
	 * @return \Symfony\Component\HttpFoundation\Cookie
	 */
	protected function createRecaller($value)
	{
		return $this->getCookieJar()->forever($this->getRecallerName(), $value, null, null, true);
	}
}

Now that we have our custom guard class we need to tell Laravel to use this new class. While not completely intuitive the best way to do that is to configure a custom auth driver where we wrap the default EloquentUserProvider class in our new SecureGuard class. Add the following to your global.php file.

<?php
/*
|--------------------------------------------------------------------------
| Auth Driver
|--------------------------------------------------------------------------
|
| Extend the auth driver to support secure cookies.
|
*/

Auth::extend('SecureAuth', function($app)
{
	$model    = $app['config']['auth.model'];
	$provider = new Illuminate\Auth\EloquentUserProvider($app['hash'], $model);

	return new SecureGuard($provider, $app['session.store']);
});

Finally update your auth.php config file to set the new auth driver.

'driver' => 'SecureAuth',

Dealing with errors in nginx can be a frustrating experience if nginx isn’t configured correctly. Sadly, the default value for error log is less than optimal and some of the tricks to getting information from nginx are not obvious. This post is intended to be a reference for the tools nginx provide and how to configure them; as well as a general guide on what’s important when facing issues in nginx.

I will probably be vilified for putting this as the first thing, however. Knowing the basics is the most important part to understanding the more difficult issues not just related to syntax. Don’t skip basic nginx syntax or how an nginx request flows. Once you understand these concepts the non-error issues become far more tangible to work with.

The Error Log

For issues where there’s an error involved, having nginx configured correctly is absolutely essential. The error_log directive should be configured with an error log level of warn, either at server or http level depending on whether you want per-vhost logs or server wide logs.

Read More

Remember register globals? Remember how you had to code as if it was off, because it might be? Remember how you had to consider the security implications of it being on, because it might be? The might be and might not be is something which has plagued a lot of early PHP features. Register globals is in no way alone in this, in the effort of making things versatile the PHP developers managed to introduce the worst of both worlds and the best of none. At least for code where you can’t guarantee 100% control over the environment your code would be running in.

We see this even today with things such as short open tags. Ever been told you shouldn’t use them? Yeah, that’s primarily because they could be turned off thus leaking your source code into the document. (To a lesser degree it’s also about XML incompatibility)

Today I want to cover a very known feature, which many people don’t often think of as being in the same group as register globals and short open tags. Namely path info. The idea of path info is brilliant enough, it is most often used as a way to have SEO “friendly” URIs in cases where one might not be able to rewrite the URL. In short, you can have a URI like so:

Read More

Lately I’ve been working with a friend on a daily-deal aggregator. The Groupon-like sites are popping up everywhere and the market for aggregators is still fairly unfilled. My project, Alladeals, target the Swedish daily deals market and as such it needs to support Swedish characters. In future it might have to support other languages as well so I decided that UTF8 was the way to go. Since most webpages are encoded in UTF-8 these days it has been fairly painless to actually work with UTF-8 in PHP, that is, until yesterday.

PHP does not natively support UTF-8. This is fairly important to keep in mind when dealing with UTF-8 encoded data in PHP. Usually I’m pretty good at remembering that, however yesterday I happened upon a bug which could easily have gone unnoticed for months if not for some good luck.

The bug manifested itself in the deal titles, the design is not well suited for really long titles so it was decided that it would be best to make sure that the titles did not exceed a length of 140 characters. To cut the the title the following code was used:

Read More