Laravel : calling your own API

Standard

If you are using Laravel to develop PHP websites (you should if you are not using it!) you will usually create your own API. If you create an API, most of the time it is because you will need to call this API from outside your website. But sometimes you want to call your API from your website. And it’s not always easy to call your own API. Let’s see a few common mistakes (it took me 1 hour to figure this out) and how to solve them.

Calling your API with no parameters

No problem here, you can use the following code:

$request = Request::create('/api/page/'.$idPage, 'GET');
$instance = json_decode(Route::dispatch($request)->getContent());

Calling your API with parameters

This is where it gets tricky. Imagine you want to call the following URL:

http://example.com/api/page/1?section=howto

If you change the previous code with something like that:

$request = Request::create('/api/page/'.$idPage.'?section=howto', 'GET');
$instance = json_decode(Route::dispatch($request)->getContent());

And if you try to do something like this in your API:

public function show(Page $page)
{
     if (Input::has('section'))
     {
          // code
     }
 }

You will not be able to get the section parameter in your API controller with Input::has('section').

But why?

In fact Input is actually referencing the current request and not your newly created request. Your input will be available on the request instance itself that you instantiate with Request::create(). If you are using Illuminate\Http\Request in your API, then you can use $request->input('key') or $request->query('key') to get parameters from the query string. But you have a problem if you are using the Input facade in your API.

A solution (so that you can continue using the Input facade) is to replace the input on the current request, then switch it back.

// Store the original input of the request
$originalInput = Request::input();

// Create your request to your API
$request = Request::create('/api/page/'.$idPage.'?section=howto', 'GET');
// Replace the input with your request instance input
Request::replace($request->input());

// Dispatch your request instance with the router
$response = Route::dispatch($request);

// Fetch the response
$instance = json_decode(Route::dispatch($request)->getContent());

// Replace the input again with the original request input.
Request::replace($originalInput);

With this you will be able to use your original request input before and after your internal API request. The Input facade in your API will be able to fetch the right parameters.

Proper internal requests

You have seen how to make internal requests to your API, but the code is not so beautiful. If you are making only a request sometimes, it is okay to use the previous example. But if you need to do several requests to your API, you will need a cleaner code.

There is a plugin for that: Laravel HMVC, available on GitHub. With it, you will not need to replace the input for your requests to your API. You will be able to do something like that:

// GET Request.
API::get('user/1');

// POST Request.
API::post('user', array('title' => 'Demo'));

// PUT Request.
API::put('user/1', array('title' => 'Changed'));

Convenient isn’t it? You can add it to your composer.json file:

"teepluss/api": "dev-master"

HTTP error when uploading an image in WordPress

Standard

This morning I came across a problem when trying to upload an image to my WordPress blog. This error just said “HTTP error”. I noticed that if I tried to upload a very small image (< = 100 kb), everything was fine. After some Google queries (and a lot of things that said you should put this in .htaccess), I fixed this issue.

Origin of the problem

The problem was caused by FastCGI. When using PHP as FastCGI, if you try to upload a file larger than 128 kb, an error “mod_fcgid: HTTP request length XXXX (so far) exceeds MaxRequestLen (131072)” occurs and causes a 500 internal server error. This happens because the value of MaxRequestLen directive is set to 131072 bytes (128 kb) by default.

Correction of the problem

To fix this, you should change the MaxRequestLen directive from the file fcgid.conf. Locate this file:

$ locate fcgid.conf

It’s usually located at edit /etc/httpd/conf.d/fcgid.conf or /etc/apache2/mods-available/fcgid.conf and add (or replace this line):

MaxRequestLen 15728640

With this, the MaxRequestLen will be 15 MB. Restart your web server and you should be fine!

$ sudo service apache2 restart

Providing a simple 2-step authentication for your app with Google Authenticator

Standard

In this article I will show how simple is it to code in PHP a 2-step authentication for your application thanks to the Google Authenticator application for your smartphone.

Requirements

You will need Composer for your computer and the Google Authenticator application on your smartphone.

Coding

Let’s start! Create an empty directory, and put this simple composer file inside.
Open a terminal in the directory you just created and run
Now you have the famous vendor directory with the package that we need. You can view it on GitHub here: https://github.com/mauroveron/laravel-google-authenticator.

Let’s create our main file. We are not going to code a entire connection system, I will just show you how you can code a 2-step authentication system. The user will have to download the Google Authenticator application, scan a barcode and then he will have a 6 digits code every 30 seconds from the application. You will ask for this code if he has previously entered his password successfully.

Put this file in the same directory.

If you want to test this code, run this command from your terminal:

Open your browser, go to http://localhost:8080, scan the barcode from the Google Authenticator application and refresh the page. The current code (given by the website) should follow what is written on your phone. You should have something like this in your Google Authenticator app.

Conclusion

And… That’s it! You know how to generate a secret key for a user, the barcode associated with it and you have a function to check if the user has entered the right code. Of course you will have some work to do if you want to implement it into your website: you will have to explain to your users how to install the app, how to scan the barcode, to save their secret key in your users table and add a step to your login process.

But it’s not so difficult 🙂