Sunday, October 23, 2016

Laravel 5.3 : Integration of API Authentiation (Passport)

Hi Everybody

Today we will learn how to itegrate Passport in laravel 5.3 and generate tokens password grant client. Laravel Passport provides a full OAuth2 server implementation for our Laravel application. APIS do not maintain session state between requests. So we need a tokens to Authenticate users. 

Step 1 : Go to your project folder and Install Passport via the Composer package manager with following command.

 composer require laravel/passport  

Step 2 : Register the Passport service provider in the providers array of  yourconfig/app.php configuration file:

Laravel\Passport\PassportServiceProvider::class,
Step 3 : The Passport service provider registers its own database migration directory with the framework, so we should migrate our database after registering the provider. The Passport migrations will create the tables our application needs to store clients and access tokens:

php artisan migrate
Step 4 : We should run the passport:install command. This command will create the encryption keys needed to generate secure access tokens. In addition, the command will create "personal access" and "password grant" clients which will be used to generate access tokens:

php artisan passport:install

Step 5 : After running this command, add the Laravel\Passport\HasApiTokens trait to our App\User model. This trait will provide a few helper methods to our model which allow us to inspect the authenticated user's token and scopes:

<?php

namespace App;

use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;
}
Step 6 : We should call the Passport::routes method within the boot method of our AuthServiceProvider. This method will register the routes necessary to issue access tokens and revoke access tokens, clients, and personal access tokens:

<?php

namespace App\Providers;

use Laravel\Passport\Passport;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy',
    ];

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        Passport::routes();
    }
}
Step 7 : Finally, in our config/auth.php configuration file, we should set the driver option of the api authentication guard to passport. This will instruct our application to use Passport's TokenGuard when authenticating incoming API requests:

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],
Above step also mentioned in laravel official document for installing Passport.

Now go to your controller, where we want to generate access and refresh token. Inside the controller write the following script.

 $http = new GuzzleHttp\Client();  
 $oauth_client = DB::table('oauth_clients')->where('name', '=', 'Laravel Password Grant Client')  
   ->where('password_client', '=', 1)->first();  
 $response = $http->post(url('/') . '/oauth/token', [  
   'form_params' => [  
     'grant_type' => 'password',  
     'client_id' => $oauth_client->id,  
     'client_secret' => $oauth_client->secret,  
     'username' => $request->email,  
     'password' => $request->password,  
     'scope' => '',  
   ],  
 ]);  
 $response_body = json_decode((string)$response->getBody(), true);  
 $access_token = $response_body['access_token'] ;  
 $refresh_token = $response_body['refresh_token'];  

Now token is generated through password grant client.

Thanks



Saturday, October 8, 2016

Laravel ajax and 500 internal server error

Hi Everyone

Today, we will learn what are the reason and their solution behind the 500 internal server error when using ajax in laravel. Sometimes when we use ajax with Laravel, it gives 500 internal server error. Following are the reasons:

CSRF:

The common reason behind 500 internal server error is missing CSRF token. In Laravel, CSRF token is required for all forms. People generally forget submitting the token with ajax request. Submitting token less ajax request results in 500 internal server error.

To fix this,  just add a hidden field in the form. Below is the code for us to add in our form:

1. For Blade Template Users:

 <input type="hidden" name="_token" value="{{ Session::token() }}">  

2. For non Blade Users:

 <input type="hidden" name="_token" value="<?php Session::token() ?>">  

3. Directly as ajax data:

 var request = $.ajax({  
  url: "test.php",  
  method: "POST",  
  data: { _token : <?php Session::token() ?>},  
  dataType: "html"  
 });  

This will solve your problem.

Other reason for this might be

WRONG ROUTE:

You may be submitting ajax data to wrong route type and even wrong url (404). So first double check the path you are submitting to. Second, check whether the route accepts “Post” or “Get” data type.
Because submitting post data via Get method or vice versa will results in Laravel ajax giving 500 Internal Server Error.

DATA TYPE RETURNED:

If you are returning Boolean and your ajax code is set for Json or any other data type then chances are that you will get internal server error. Try to set data type for all ajax response to json. If you are using jQuery then set dataType to xml.

 var request = $.ajax({  
  url: "/action",  
  method: "POST",  
  data: { id : userId },  
  dataType: "json"  
 });  

CROSS DOMAIN CONFIGURATION:

If you are using ajax for cross domain requests then be sure that you are sending proper headers.
In case of jQuery, just set the crossDomain variable to true. Alternatively set dataType to “jsonp”

.HTACCESS

Check your .htaccess file for any error specially after you have edited it.

Hope this will help someone.

Thanks