Tuesday 17 October 2017

Encryption user data in Laravel

Hi Everybody,

As you know, if you want user data(email, name etc) security in db, then you must encrypt data.
So at the time of adding data you need to encrypt data and at the time of retrieve data you need to decrypt data.
Below is the implementation of encryption and decryption of user data in Laravel

in Model(User.php)

<?php

namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Traits\EncryptableTrait;

class User extends Authenticatable {
{
    use EncryptableTrait;

    protected $table = 'users';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['role_id', 'user_type', 'first_name', 'last_name', 'email', 'password', 'is_verified', 'status'];


    protected $encryptable = [
        'first_name', 'last_name', 'email'
    ]; 

}


Here i have written encrypt and decrypt code in trait EncryptableTrait.php

<?php
namespace App\Traits;

use Illuminate\Support\Facades\Crypt;

trait EncryptableTrait {

    protected $encryptKey;

    public function getAttribute($key)
    {
        $value = parent::getAttribute($key);

        if (in_array($key, $this->encryptable) && ( ! is_null($value)))
        {
            $value = $this->deCryptData($value);
        }

        return $value;
    }

    public function setAttribute($key, $value)
    {
        if (in_array($key, $this->encryptable))
        {
            $value = $this->encryptData($value);
        }
        return parent::setAttribute($key, $value);
    }

    private function encryptData($value)
    {
        $encryptValue = '';
        $cbSrc = strlen($value);
        $encryptKey = \Config::get('app.encryption_key');
        $encryptKeySize =  strlen($encryptKey);   
        for($NdxKey = 0, $i = 0; $i < $cbSrc; $i++)
        {
            $encryptValue .= sprintf("%02X", (ord($value[$i]) ^ ord($encryptKey[$NdxKey++])) & 0xFF);
                        
            if ($NdxKey >= $encryptKeySize)
                $NdxKey = 0;
        }
        return $encryptValue;   
    }

    private function deCryptData($value)
    {
        $decryptValue = '';
        $cbSrc = strlen($value);
        $encryptKey = \Config::get('app.encryption_key');
        $encryptKeySize =  strlen($encryptKey);   
        $deVal = null;
        
        for($NdxKey = 0, $i = 0; $i < $cbSrc; $i += 2)
        {
            sscanf($value[$i] . $value[$i + 1], "%x", $deVal);
            $decryptValue .= sprintf("%c", ($deVal ^ ord($encryptKey[$NdxKey++])) & 0xFF);
            
            if ($NdxKey >= $encryptKeySize) 
                $NdxKey = 0;
        }
        return $decryptValue;   
    }

?>

Note:-You can use laravel predefined encrypt method here, but this method give you different encrypt string for same string, but the method i have used provide same encrypted value all time

in config/app.php

    'encryption_key' => env('APP_KEY'),

This APP_KEY should never change.

Thanks.

Browser back button after logout Laravel

Hi Everybody,

After a long time i am posting this.

It is normal issue, after logout when user click on browser back button, it display dashboard or after login pages some time.
So fix this issue in laravel we can use middleware.

Create middleware

php artisan make:middleware RevalidateBackHistory
Within RevalidateBackHistory middleware, we set the header to no-cache and revalidate.
<?php
 
namespace App\Http\Middleware;
 
use Closure;
 
class RevalidateBackHistory
{
 /**
 * Handle an incoming request.
 *
 * @param \Illuminate\Http\Request $request
 * @param \Closure $next
 * @return mixed
 */
 public function handle($request, Closure $next)
 {
 $response = $next($request);
  
 return $response->header('Cache-Control','nocache, no-store, max-age=0, must-revalidate')
 ->header('Pragma','no-cache')
 ->header('Expires','Fri, 01 Jan 1990 00:00:00 GMT');
 }
}
Update the application’s route middleware in Kernel.php
protected $routeMiddleware = [
    .
    .
    'revalidate' => \App\Http\Middleware\RevalidateBackHistory::class,
    .
    .
    ];
And that’s all! So basically you just need to call revalidate middleware for routes which require user authentication.

Thanks...

Friday 17 February 2017

Can I do a CURL request to the same server?


Hi Everybody,

If you want to implement a way to make POST calls to pages located on the same server or in another server. We cannot use include because the files that we are calling usually call different databases or have functions with the same name.
For this post call we can use curl, and while it works perfectly when calling files from another server, but if you make call fron the same server it will create deadlock condition.

e.g 
File1.php

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "www.myserver.com/File2.php");
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
$result = curl_exec($ch);
curl_close($ch);
echo $result;
?>

File2.php
<?php
echo "I'M IN!!";
?>
 
In this example, after calling File1.php, you do not get any output, but if File2.php is in another server then you get a result.

Solution of this curl deadlock


Be aware that if you're issuing the CURL request to your own site, you're using the default session handler, and the page you're requesting via CURL uses the same session as the page that's generating the request, you'll run into a deadlock situation.

The default session handler locks the session file for the duration of the page request. When you try to request another page using the same session, that subsequent request will hang until the request times out or the session file becomes available. Since you're doing an internal CURL, the script running CURL will hold a lock on the session file, and the CURL request can never complete as the target page can never load the session.

You can, just make sure that the script doing the CURL request closes the session with session_write_close() immediately before the curl_exec(). You can always do a session_start() again afterwards if you need to change anything in the session



 File1.php

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "www.myserver.com/File2.php");
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
session_write_close() 
$result = curl_exec($ch);
curl_close($ch);
session_start() 
echo $result;
?>

File2.php
<?php
echo "I'M IN!!";
?>
 
Now this will work for same serve as well as different server.
 
Thanks. 
 


Saturday 28 January 2017

New features in Laravel 5.3.

Hi everybody,

This is after a long time, but having information about new features in Laravel 5.3.

Blade's foreach $loop


This new release introduces a $loop variable inside a foreach loop. This variable provides a couple of properties that can help us easy manage indexes, increments in loops etc. Now in Laravel 5.3, we can do stuff like.

<ul>
    @foreach ($countries as $country)

        @if ($loop->count)
            @if ($loop->first)
                <li class="list-item list-item--header">{{ $country->name }}</li>
            @elseif ($loop->last)
                <li class="list-item list-item--footer">{{ $country->name }}</li>
            @else
                <li class="list-item">{{ $country->name }}</li>
            @endif
        @endif

    @endforeach
</ul>

# Multiple Migration Paths


If you have ever installed a Laravel package that needs a database migration, it involves you copying some migrations into the migration folder, but with Laravel 5.3 — a package can define its migration path, and when you run php artisan migrate all migrations will run without you having to clutter your migration directory.

To let Laravel know about another migration directory, simply do.

$this->loadMigrationsFrom('path/to/migrations/folder');

# Query Builder Returns a Collection


The query builder used to return an array. If we wanted to perform a large array of operations on the returned dataset, we would have to loop through the array. But collections makes that really simple for us to handle. So because of that reason, the query builder just like the ORM now returns a collection of objects. There is a pull request on the topic.

Now we can do stuff like this.

$result = DB::table('posts')->get();

if ($result->first()) { }
if (!$result->isEmpty()) { }
if ($result->count()) { }
if (count($result)) { }

This was not available before. Now, we can do cool operations like pluck, filter etc.

# Migration Rollback in Steps


Instead of rolling back our entire migrations, we can now rollback in steps. With the new step flag added to artisan. So, now we can do this.

php artisan migrate:rollback --step=1

# Ability to Customize Simple Pagination


Laravel is bringing back the ability to customize simple navigation with views. You can also still use the pagination templates if you want, but this is still a nice feature to have. We can do stuff like this.

<ul class="pagination">

    @if ($paginator->onFirstPage())
        <li class="disabled"><span>«</span></li>
    @else
        <li>
            <a href="{{ $paginator->previousPageUrl() }}" rel="prev">«</a>
        </li>
    @endif

</ul>


# Laravel Echo


Echo is meant to be an improvement over the current event broadcasting system. It seamlessly integrates with pusher's JavaScript library.

Taylor Otwell has made a video to better explain Echo. Echo also has an npm package that makes using sockets on the frontend easier.

# Misc and Conclusion


Other features included with version 5.3 are:

    Eloquent Collections are cleanly serialized and re-pulled by queued jobs.
    Queue console output changed to show the actual class names.

    firstOrCreate: now allows additional parameters.

In conclusion, maybe in a major release — support for MongoDB.