Tag Archives: Programming

CakePHP3 with Hashids

Security by obscurity is never a good policy but there are still some legitimate reasons why you would want to hide your id’s. One good reason is that you don’t want to reveal how many users you perhaps have or at what rate your membership is growing. Making it difficult for the average website visitor to cycle through your id’s by just changing the URL is also important.

The following code should be used with other security measures that check that a user is authenticated and authorized to access a particular record or group of records. The implementation of such security is outside the scope of this article. Reading the CakePHP3 manual should provide you with enough detail on how to achieve this or alternative you should read my previous blog post on using CakePHP3 with TinyAuth.

Install the Hashids Library

The following is all based around using the excellent Hashids.org library. The library has been ported to a huge number of languages. You should visit the website and read the docs for more specific information.

All CakePHP3 users should be familiar with composer, so using the following method to install Hashids is prefered.

Update AppController

Add the following code to your AppController

Notice you can set a couple of parameters. First you need to create your own “salt” just vist random.org and generate a string of characters. You can also change the “min_hash_length” and change the “alphabet” characters that are used for string generation.

Using Hashids in Controllers

Encoding and decoding id integers is now super easy.

Typically I use the decode function inside of controllers as the id string will already be encoded inside the view template and passed back to the controller.

Using Hashids in Template Views

First we need to pass an instance of hashids() to the view. We do that with $this->set().

The important bit is this.

Then inside of views we can access the hashids() object.

You can also use this inside loops to encode or decode lists of id’s and so forth. Let me know if it helped you out or you think the code can be improved.

That’s really all there is to it!

[box type=”alert” size=”large” style=”rounded” border=”full” icon=”empty”]Since writing this article a better cleaner solution is available from the UseMuffin Team. I recommend the UseMuffin/Obfuscate CakePHP 3 Plugin: https://github.com/UseMuffin/Obfuscate

This plugin supports a variety of external obfuscation libraries and the behavior can be configured on a per Model basis.[/box]

CakePHP 3 with TinyAuth & Blame

I want to walk you through a blank CakePHP 3 setup and install a few worthwhile plugins. The primary goal of this post is to show how to setup Dereuromark’s TinyAuth plugin which is fantastic however may leave a few newbies scratching their heads trying to get it set up. So what follows will be a cookbook style approach with copy and paste code.

There is a number of ways we could setup TinyAuth and these are outlined in the manual however I’m just going to show you the Users HasAndBelongsToMany Roles method that way you should see how to revert back to the other “Role Base Access Control” possibilities.

So let’s get started.

Download CakePHP 3

Change [app_name] to the name of the folder that will house your application.

You may also need to make sure the the cake bake feature has the right permissions set. Run the following if you get a permissions error when using the migration commands below.

Create Table Migrations

We’ll need three tables for this to get us started, users, roles and roles_users table. Open your terminal and run the following.

Make sure you have setup your database connection in config/app.php otherwise you will get an error when trying to run the migration commands.

Once the commands above have run successfully you should have 3 new migration files in config/Migrations. Next open up all 3 files in your favorite editor and drop in the following code.

Place this code in your create_user_table.php file.

Next place this code in your create_roles_table.php file.

Next place this code in your create_users_roles_table.php file.

Now run your migrations in your terminal us follows.

 Bake All

Run the cake bake command to create all your models, views and controllers.

 Load Plugins

Ceeram Blame

Next lets load in the plugins we will use. Ceeram’s Blame plugin keeps track of who changed what. You will notice the created_by and the modified_by fields in both the Users and Roles Table. All future tables should also contain those integer fields if you need to keep track of changes made by users.

 Dereuromark TinyAuth

Run the following to load Dereuromark’s TinyAuth.

 Edit Bootstrap.php

Next edit your config/bootstrap.php file. Load the following plugins.

 Authentication with Cake Auth

Let set up the login, logout part of our website. Open up src/Controller/AppController.php and load the auth component with a few settings passed in. Notice we have setup the “authorize” part to use TinyAuth.

Next open up src/Controller/UsersController.php and add the following login, logout methods.

Let’s also add a beforeFilter method that will allow as to override certain method/views so that unlogged in users can access certain parts of the website. Do this for both the User and Role Controller.

Now open up src/Template/User and create a new file called login.ctp then add the following

Next open up src/Model/Entity/User.php and add the following to hash the password.

 TinyAuth acl.ini

Last but not least we need to create an acl.ini file in our config folder. Add the following as a starting point.

Your app should now be fully secured. Try login into to any location such as users/index and you should be bounced back to users/login.

Blame Someone

Lets finalise the Ceeram Blame plugin. We needed to setup the authorization in order for the Blame plugin to know who was logged in so that it can associate a user id with the created_by and modified_by fields.

Simply add the following to your AppController

Next add the Blame Behavior to each of the Role and User models. Go to src/Model/Table.

 Finished

Now you should have a full working login, logout app with the ability to set up role types and set permission for your views! Awesome!

If you have trouble please check out my git repo and compare the code. Alternatively you can clone my repo for a starting point for your next cake project. Download from BitBucket: cakephp3-loaded

[box type=”alert” size=”large” style=”rounded” border=”full” icon=”empty”]Since writing this article a better cleaner solution is available from the UseMuffin Team. Instead of the Blame (depreciated) Plugin I recommend the UseMuffin/Footprint CakePHP 3 Plugin: https://github.com/UseMuffin/Footprint[/box]

CakePHP3 Database Migrations with Phinx

[dropcap]C[/dropcap]ontinuing on from my last post CakePHP3 Database Migration Commands as I promised this is a follow up with actual working examples that you can use right away. The database migrations I have put together use CakePHP3 Model & Database Conventions and so you can be sure all tables will be picked up and correctly related to each other with a “bin/cake bake all {model}” command.

I thought we could create a simple “countries” and “states” model/table migration. This will give us an idea how to create a Migration for each database table and also how to create the Migration with a has many foreign key relationship.

Create Countries Table Migration

So let’s start by creating a new Migration that will allow also to create a “countries” table.

This will generate an empty migrations file in “config/Migrations”. The migration file should have a datetime stamp appended to the file with create_countries_table. So your file should look something like this “20150316082226_create_countries_table.php”.

Next we need to open this file and add our code that will create the countries table. So our countries table will have the following fields and data types, id(integer), name(string), acronym(string), created(datetime) and modified(datetime). The created and modified field are special CakePHP fields that will be automatically updated when database records are created or edited. This is a “behavior” that is attached to the Model/Table/CountriesTable class when we use cake bake.

The Up Method

So there is a little bit happening here, there are three methods that are automatically generated by CakePHP Migrations (Phinx), that is the change, up and down methods. The change method is commented out by default. We are only concerned with the up and down. Within the UP method we are calling a table object and passing into it declarations. In it’s most basic form it’s simply as follows.

Describe the Table

Obviously you need to tell Phinx what you want to name the column and the type of columns you need e.g. integer, string, text, datetime and so on. For more please see the Phinx Valid Column Types. See the basic example below. Notice that we also added an index to the name column. Also note that we have specified a “length” of 255 to the name column. This will create a varchar(255) column in our database. We have also specified “null” as false, this is a default behavior and so it doesn’t need to be stated however I like to be verbose as it makes it easy to simply change it in the future if you later decide to allow null on that column.

In the above example by default Phinx will create an ID column for you named “id”. If you need to override this you can turn off id => false and specify you own id field with ‘primary_key’ => [‘your_id’]. So depending on your table naming conventions you can leave it or override the default behavior. Example with id override below.

Note that because we have specified our own id column we can have control over it’s attributes. Signed false means that it’s cannot have a – or + symbol in front of it. The identity true attribute means the field will be auto_incremented with a unique id each time a new row is created.

Insert Data

After the table is created you can use the following code to perform database tasks with SQL. The most common thing you might do is insert some default or dummy data.

The Down Method

Migrations are all about being able to reverse changes or “rollback” database tables to a previous state. So note in the down method you can place the following code.

Migrate the Database

Now just run the command line migration tool

Using your favorite database tool like Sequel Pro or MySQL Workbench you should see a new countries table in your database. If you wish to rollback use the following command line. Run the rollback command for each migration.

Add States Table Migration

Let’s now create our States Migration. Run the following in your terminal.

Now find the newly generated create_states_table.php file and add the following data into your up and down methods.

This migration includes all the column specifications. You will see a few new ones. The most important is the “country_id” foreign key column to link us to our countries table. This is named country_id and not countries_id according to the CakePHP convention. This makes sense as the states.country_id is only referring to a single parent country.

There are also a few interesting column types to suit longitude and latitude information. Make sure you look closely at the column type and the new attributes.

The rest should be much the same as the CreateCountriesTable migration.

Add Foreign Keys Migration

Next we need to add a foreign key constraint to the states table. This will link the states table to the countries table on the states.country_id colum to the countries.id column.

I personally prefer to create a separate migration for all my foreign keys. I also usually make this the very last migration after all my tables have been created. The reason is because when you rollback all the foreign keys need to be dropped first from all the tables in the database. This will allow you to rollback and drop the previously created tables without an error. If you don’t drop the foreign keys before you attempt a rollback the migration will fail because of a foreign key check error. The opposite is also true, if you try to migrate a table with foreign keys and the linked table hasn’t been created yet the migration will fail.

So let’s do the following in the terminal.

Open up the generated add_foreign_keys.php file and dump in the following code.

Notice that the code for adding and dropping a foreign key are almost the same but see the subtle differences.

Migration Complete

Just one more thing, re-run that migration again in the command line.

For more helpful tips on CakePHP3 Migration Commands see my last post.

I hope that’s given you an insight into how to handle CakePHP migrations in any new CakePHP3 project you might undertake. The advantages of migrations are evident, you can keep it under source control and all members on your team can stay on the same database schema.

This knowledge however is not restricted to the CakePHP3 framework, you can include the Phinx Migration library into any PHP project. So your new found knowledge is portable.

Go migrate something!

CakePHP3 Database Migration Commands

A list of a few helpful commands to use when creating database migration files.

Check the status of migrations

This would show something like the following

 Migrate (up) All Pending Migrations

 Rollback (Down) Last Migration

 Create a New Migration File

The above command should be used for each table you create or any table modification you perform. It’s good to keep each migration name descriptive so for example if I was creating a maps table I would name my migration CreateMapsTable. NOTE: CakePHP3 (Phinx) migrations require that you use CamelCase for migration names.

My next post will explain how to create database table migration files with a table example for both up and down methods.