Laravel: Should I Choose HHVM or PHP-FPM

My conclusion:
HHVM beats PHP-FPM by 20% to 45% at both request per second and average response time.

Well, if you also include database operation, the time margin should be around the same (the percentage may differ though), considering both HHVM and PHP-FPM consume about same time for database operation.

I ran the test for Lumen 5.2 and Laravel 5.2 using Apache Bench. The PHP version used is 5.6.13 and NGinx version 1.4.6.

If you are curious of “even better performance for Laravel”, try ReactPHP+NGinx (refer to http://marcjschmidt.de/blog/2014/02/08/php-high-performance.html) because it eliminates Laravel bootstrap’s code just being ran once at server startup, instead of ran at each request (See also https://github.com/php-pm/php-pm). But there is a fatal drawback: If your code throw uncatched exception, your server dies. Also other drawbacks such as reload server on code change and potential memory leaks.

If you need the test results / source code, just contact me. I don’t feel like putting them on this blog.

Gap

Few weeks ago I stumbled upon a manga title that I already readed, The World God Only Knows (TWGOK). So, I took initiative to re-watch the anime. The series is about a boy who uses love to cast out runaway spirit that hide on gir’s gap of heart, and catch it.

This is Keima, MC (Main Character) of the series
This is Keima Katsuragi, MC (Main Character) of this series

It turns out the ending left gap on my heart… (it’s a bit different with the manga, and better)

My mind was starving and re-watched the anime again and re-read the manga. I was insatiable. My heart felt empty yet serene, and I questioned what’s the importance of love anyway.

Even my nickname on students committee jacket is influenced
Even my nickname on students committee jacket is influenced

<aside>

This week, I recount that I haven’t attended islamic talk, because the regular event got halted since this weeks is The Birthday of Our Propeth Muhammad. So, today I attended a talk nearby.

The point is, if a heart is not filled with quran, then it would be filled with demon. I see an intersection between the series and the reality. As I recount, I also haven’t recite quran and study islam enough recently.

Well then, I found the method to close gap on my heart, by filling it with quran.

I wonder if this method works in the series :))

</aside>

If you are interested, you can see the creator’s blog (it’s japaneese)

Enable Upload Large File on PHP + Nginx

  1. Open file php.ini (should be located at /etc/php5/fpm/php.ini if you are using PHP-FPM. Otherwise, just find it using: sudo updatedb && locate php.ini)
  2. Edit these 3 variables:
    1. upload_max_filesize => 2M to (whatever you want. I tend use 128M)
    2. post_max_size => 2M to (same as above. just note if you expect to upload multiple files, set this variable higher than above)
    3. max_input_time => 60 to (your client’s expected maximum upload time. should be max file size divided by minimum client’s upload speed)
  3. Open your nginx configuration, add this parameters:
    1. client_max_body_size xxM; (same as post_max_size)
    2. fastcgi_read_timeout xxM; (same as max_input_time)
  4. Restart PHP-FPM and nginx: sudo service php5-fpm restart && sudo service nginx restart
  5. That’s all folks!

Unify Laravel Authentication / Session Across Apps

Question: Is it possible to make single login authentication for multiple laravel apps on same domain?

Condition: Laravel stores session on two places: client-side on encrypted HTTP cookie and server-side on (optional) encrypted key-store value.

Idea: Make each apps reads the same session both on client-side and server-side and make sure both application reads same ‘users’ table.

How to unify client side:

  1. Open config/session.php
  2. Find ‘cookie’ parameter
  3. By default the value should be ‘laravel_session’. It’s okay to put there, or if you want you can change that to other name. Just note that this value must be same accross application
  4. Open .env
  5. Set same 32 string length APP_KEY for each application

How to unify server side (using redis as session manager):

  1. Install redis (if you have not)
  2. Install predis package (if you have not)
  3. Open .env
  4. Change CACHE_DRIVER to redis for each application

That’s all folks !

Well, there are other configurations to think of such as cookie domain, cookie path, session encryption, and redis clustering. You should look them if you need to.

Struggling with Laravel 5.0 Password

I was developing “a Laravel 5.0 system”. At first, there was no problem with authentication.

After 5 months development, the login feature turns out to be broken. Last time I remember it was fine before. So I tried logging in with my own account and I can log in normally. Then the developer points out that only newly registered users who was not able to login.

Then I open the users table and took my bcrypt-ed password and tested it online. Turned out my old account can be verified and my newly created account cannot be verified. Then I look into registration file at app/services/registar.php and dd-ing some variables. And tested the bcrypted-password online. Then I tried dd-ing bcrypted password (without inserted to laravel model) and it was fine!

password
Look man, the password changes anytime I change the password on User Eloquent model

So, my first conclusion was Storing password in User Eloquent model is different than the specified value.

apt-get update && apt-get upgrade
No Luck.

Then I suspect Laravel changed my password abruptly. I tested storing the password using plain text, and tested the hash, and it was verified!.

So, the conclusion is, laravel calls bcrypt function upon password assignment without developer consent, which is weird I think, as they changed the behavior that cause my-5-months-code broke.

The fix is easy, just change

'password' => bcrypt($data['password']),

into

'password' => $data['password'],

(String) Password for Authentication

Manakah yang lebih baik:

  • naruh hashed password di server dan minta plain text dari client, atau
  • minta hashed password dari client dan di-cek dengan plain text pada server ?

Kalau kita breakdown lagi, ada beberapa cara pengiriman-penyimpanan untuk verifikasi password dalam bentuk string:

  • Client side
    1. Kirim plain text
    2. Kirim encrypted text
    3. Kirim standard hash, hanya md5(password) saja
    4. Kirim private salted hash, md5(private salt + password)
    5. Kirim random salted hash, md5(random salt + password)
  • Server side
    1. Simpan plain text
    2. Simpan encrypted text
    3. Simpan standard hash, hanya md5(password) saja
    4. Simpan private salted hash, md5(private salt + password)
    5. Simpan random salted hash, md5(random salt + password)

Kombinasi-kombinasi diatas bisa dipasangkan sesuka hati, hanya saja kalau pake random salted hash, pasangannya tidak boleh hash lagi (karena tidak bisa di-cek passwordnya). Dan private salted hash hanya bisa dengan private salted hash lagi / plaintext.

Menurut saya

Metode Komentar
1. Plain Text Sangat berbahaya. Kalau client ngirim plaintext mudah sekali diintercept oleh eavesdropper. Selain itu, kalo entri password kehack, sangat berbahaya ketika password semua user ketauan. Bisa2 merembet ke semua akun pengguna selain akun sistem terkompromi.
2. Encrypted Text Di sisi client bisa diasumsikan aman, apabila menggunakan SSL (walaupun tidak bisa juga dibilang 100% aman. tapi harusnya sih aman). Kalau di sisi server agak berbahaya ketika key decryptionnya dapet. Bisa-bisa terekspose seperti plaintext.
3. Standard Hash Ada bahayanya. Bisa kena attack rainbow table. Banyak situs di internet yang bisa reverse dari kode hashed md5 / sha1 ke plaintext.
4. Private Salted Hash Jauh lebih aman daripada standard hash karena ada key rahasia untuk pembuatan kode md5 nya. Hanya saja, kalau key diketahui, hanya butuh waktu untuk membuat rainbow table nya untuk membobol semua user.
5. Random Salted Hash Sedikit modifikasi dari private salted hash, dengan hash unik untuk setiap passwordnya. Bisa dibilang best practice nya pakai metode ini. Kalaupun ada yang punya salted-hash nya, perlu brute force yang lebih berat karena harus membuat rainbow table untuk setiap password. Exhaustive brute force….

Kalau situs besar sepert Facebook, Google, dlsb, biasanya menggunakan metode Client=2 (menggunakan SSL) server=(4&5) (kayaknya)

Framework PHP seperti laravel by default menggunakan Client=1(HTTP)/2(HTTPS) Server=5

Biasanya situs-situs atau aplikasi yang tidak memikirkan security menggunakan metode Client=1 server=1

Jadi, kalo kata saya sih paling aman pakai metode Client=2 dan server=(4&5). Aman dari eavesdroper dan kalo hashed passwordnya ketauan, tetep perlu cari private key nya dan brute force.