Laravel 5 and Angular Auth using JSON Web Token (JWT) : Production on Nginx
Continued from Laravel 5 / Angular Auth using JSON Web Token (JWT), in this tutorial, we're going to do setup a new app on AWS Ubuntu 14 instance.
So, we need to do everything from scratch.
LAMP install
php:
$ sudo apt-get install python-software-properties $ sudo add-apt-repository ppa:ondrej/php5 $ sudo apt-get update $ sudo apt-get install -y php5 php5-mcrypt php5-gd php5-common
Install Nginx:
$ sudo apt-get install nginx
Install Mysql:
$ sudo apt-get install mysql-server php5-mysql
Install the missing PHP tools needed to actually run the Laravel code with Nginx:
$ sudo apt-get install php5-fpm
Open the main PHP configuration file (/etc/php5/fpm/php.ini) for the PHP-fpm processor that Nginx uses. We only need to modify one value for the cgi.fix_pathinfo parameter. We need to uncomment this and set it to "0". This is to guard against a potential attacker who may want to run a script with a similar name.
Enable the MCrypt extension, which Laravel depends on:
$ sudo php5enmod mcrypt
Since we made some changes, we need to restart the php5-fpm service:
$ sudo service php5-fpm restart
Composer is required for installing Laravel dependencies. So, run the following command to get the latest Composer version:
$ curl -sS https://getcomposer.org/installer | php $ sudo mv composer.phar /usr/local/bin/composer $ sudo chmod +x /usr/local/bin/composer
First, download the Laravel installer using Composer:
$ composer global require "laravel/installer"
We want to make sure to place the ~/.composer/vendor/bin directory in our PATH so the laravel executable can be located by our system. In ~/.bashrc:
# Laravel 5 export PATH=$PATH:~/.composer/vendor/bin
Let's go to var/www directory.
Then, clone:
ubuntu@ip-172-31-25-188:/var/www$ sudo git clone --depth=1 https://github.com/epic-math/laravel5-angular-jwt.git
Set ownership for nginx:
ubuntu@ip-172-31-25-188:/var/www$ sudo chown www-data:www-data laravel5-angular-jwt
Run the following commands to get the latest Composer version:
$ php -r "readfile('https://getcomposer.org/installer');" > composer-setup.php $ php -r "if (hash('SHA384', file_get_contents('composer-setup.php')) === '781c98992e23d4a5ce559daf0170f8a9b3b91331ddc4a3fa9f7d42b6d981513cdc1411730112495fbf9d59cffbf20fb2') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); }" $ php composer-setup.php $ php -r "unlink('composer-setup.php');"
Next, we need to run php composer install to install the dependencies:
ubuntu@ip-172-31-25-188:/var/www/laravel5-angular-jwt$ sudo composer install
"composer install will read from the .lock file fetching the exact same versions every time rather than finding the latest versions of every package. This makes our app less likely to break, and composer uses less memory." - composer killed while updating
Now let's set the 32 bit long random number encryption key which will be used by the Illuminate encryptor service:
$ sudo php artisan key:generate Application key [uvQoX9sbUSHHBYDhMADqKfsA1KZHfyYl] set successfully.
Now edit config/app.php configuration file and update above generated application key as followings. Also make sure cipher is set properly:
'key' => env('APP_KEY', 'uvQoX9sbUSHHBYDhMADqKfsA1KZHfyYl'), 'cipher' => MCRYPT_RIJNDAEL_128,
Run php artisan vendor:publish to publish JWT and CORS packages config files:
$ sudo php artisan vendor:publish Publishing Complete!
Before we migrate the database, we need to create a MySQL user, "homestead":
$ mysql -u root -p mysql> CREATE DATABASE homestead; mysql> CREATE USER 'homestead'@'localhost' IDENTIFIED BY 'password';
Run php artisan migrate to migrate the database:
$ sudo php artisan migrate Migration table created successfully. Migrated: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_100000_create_password_resets_table
Actually, I had an error saying "PDOException] SQLSTATE[28000] [1045] Access denied for user 'homestead'@'localhost' (using password: YES) looks like same error different is not showing any file line number.
So, I had to do the following things:
- Match the username, db, pass of the mysql conf. both in .env and config/database.php.
Actually, I left the password in config/database.php as blank. - We may need to clear cache
$ sudo php artisan config:clear
The following two sections are about dependency update using "composer update / composer install" and quite straight-forward. Though there are not a lot we should do at this point because everything is already into the repo we got earlier. But one thing we need to do is to set jwt secret key which is separate key from the app key.
Now JWT thing (JSON Web Token Authentication for Laravel & Lumen).
Check if jwt is in composer.json:
"require": { "tymon/jwt-auth": "0.5.*" }
To pull it in, run composer install:
$ sudo composer install
Add the following to config/app.php:
'Tymon\JWTAuth\Providers\JWTAuthServiceProvider' 'JWTAuth' => 'Tymon\JWTAuth\Facades\JWTAuth' 'JWTFactory' => 'Tymon\JWTAuth\Facades\JWTFactory'
Publish the config using the following command:
$ sudo php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"
Set a secret key in the config file using this command to generate a key:
$ sudo php artisan jwt:generate jwt-auth secret [Cin...] set successfully.
The laravel-cors package allows us to send Cross-Origin Resource Sharing headers with ACL-style per-url configuration (Cross-Origin Resource Sharing).
The defaults are set in config/cors.php. Copy this file to config directory to modify the values. We can publish the config using this command:
$ sudo php artisan vendor:publish --provider="Barryvdh\Cors\ServiceProvider" Nothing to publish
Weird. But decided to move on from this.
Check if the following is in composer.json:
"require": { "barryvdh/laravel-cors": "0.4.x@dev", },
At this point, we may want to use composer install instead of composer update. So, we need to copy our dev's composer.lock to this server.
Update dependencies:
$ sudo composer install ... Generating autoload files > php artisan clear-compiled > php artisan optimize Generating optimized class loader
(*) Note: "Run the composer update command on development machine, which generates the composer.lock file. Upload that composer.lock file and on the shared host just run composer install. This will use a lot less memory!"
composer update "process killed"I moved the code to /var/www/, and the nginx configuration looks like this:
server { listen 80; root /var/www/laravel5-angular-jwt/public; index index.php index.html index.htm; server_name demo2.epicmath.com; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { try_files $uri /index.php =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } location ~ /\.ht { deny all; } }
Then, create a symbolic link:
$ sudo ln -s /etc/nginx/sites-available/demo2.epicmath.com /etc/nginx/sites-enabled/demo2.epicmath.com
However, unfortunately, I got the following error at SignUp:
XMLHttpRequest cannot load http://jwt.dev:8000/signup. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://laravel.example.com:8001' is therefore not allowed access. The response had HTTP status code 404.
So, I looked for the "jwt.dev:8000":
ubuntu@ip-172-31-25-188:/var/www/angular-laravel5-jwt$ grep -irn jwt.dev ./ ./public/scripts/app.js:10: BASE: 'http://jwt.dev:8000', ./public/scripts/app.js:11: BASE_API: 'http://api.jwt.dev:8000/v1' ./app/Http/routes.php:65:Route::group(['domain' => 'api.jwt.dev', 'prefix' => 'v1'], function () {
After replacing the "jwt.dev" with "demo2.epicmath.com", we may want to clear cache:
$ php artisan cache:clear
Now I am able to signup and signin:
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization