How to Build a RESTful API in Laravel using JWT Authentication
RESTful API is an application program interface that uses HTTP requests to GET, PUT, POST and DELETE data.This services allow requesting systems to access and manipulate textual representations of web resources using a uniform and predefined set of stateless operations. Also in computer programming, an application programming interface (API) is a set of subroutine definitions, protocols and tools for building applications.
In this example we will use JWT (Json Web Token ) authentication package for authentication and in this example I have explain user login and registration example using REST API.
I have also add this code to my github account
Follow bellow few steps to create restful api in laravel app.
Step 1: Install Laravel
Open your terminal OR simply press Ctrl + Alt + T and add below code to your terminal to install Laravel Project.here in below code laravel-jwt-auth is project name.
composer create-project --prefer-dist laravel/laravel laravel-jwt-auth
Step 2: Install JWT-Auth package
To install JWT-Auth open your terminal and go to your project directory OR simply press Ctrl + Alt + T and add below code to your terminal.
composer require tymon/jwt-auth
If you getting any error uring installtion someting like memory error for composer that case you can add below code to your composer.json file and after update composer.
"tymon/jwt-auth": "^1.0"
composer update
Step 3: Add service provider
Add the service provider to the providers
array in the config/app.php
config file as follows:
'providers' => [
...
Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
]
Step 4: Publish the config
Run the following command to publish the package config file:
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
You should now have aconfig/jwt.php
file that allows you to configure the basics
of this package.
Step 5: Generate secret key
I have included a helper command to generate a key for you:
php artisan jwt:secret
This will update your .env
file with something like JWT_SECRET=foobar
Step 6: Update User Model
- First implement the Tymon\JWTAuth\Contracts\JWTSubject
- Add to methods
getJWTIdentifier()
andgetJWTCustomClaims()
.
I have made above changes in User.php file check it in below file.
namespace App;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable implements JWTSubject
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
// Rest omitted for brevity
/**
* Get the identifier that will be stored in the subject claim of the JWT.
*
* @return mixed
*/
public function getJWTIdentifier()
{
return $this->getKey();
}
/**
* Return a key value array, containing any custom claims to be added to the JWT.
*
* @return array
*/
public function getJWTCustomClaims()
{
return [];
}
}
Step 7: Update Auth guard
Go to config/auth.php and made below changes in file.
return [
/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session", "token"
|
*/
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'users',
'hash' => false,
],
],
/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that the reset token should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
],
/*
|--------------------------------------------------------------------------
| Password Confirmation Timeout
|--------------------------------------------------------------------------
|
| Here you may define the amount of seconds before a password confirmation
| times out and the user is prompted to re-enter their password via the
| confirmation screen. By default, the timeout lasts for three hours.
|
*/
'password_timeout' => 10800,
];
Step 8: Migrate database
To migrate default database add below code to your terminal.
php artisan migrate
Step 9: Create below route for api
To create routes for api laravel provide separate configuration for routes inside route/ap.php file.
route/api.php
get('/user', function (Request $request) {
return $request->user();
});
Route::post('api-user-registration','Api\ApiFunctionCallController@ApiUserregistration');
Route::post('api-user-login','Api\ApiFunctionCallController@ApiUserLogin');
Step 10: Create Controller for API
We will create Api folder inside app/Http/Controllers folder to manage all our API related controller and its logic.
create app/Http/Controllers/Api/ApiCommanFunctionController.php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller as Controller;
class ApiCommanFunctionController extends Controller
{
/**
* [sendResponse This function is used to send api response data]
* @param [type] $status [description]
* @param [type] $result [description]
* @param [type] $message [description]
* @return [type] [description]
* @author Chirag
*/
public function sendResponse($status,$result, $message)
{
$response = [
'status' => $status,
'data' => $result,
'message' => $message,
];
return response()->json($response, 200);
}
/**
* [sendError This function is used for send error message during api call]
* @param [type] $error [description]
* @param array $errorMessages [description]
* @param integer $code [description]
* @return [type] [description]
* @author Chirag
*/
public function sendError($error, $errorMessages = [], $code = 404)
{
$response = [
'status' => $code,
'message' => $error,
'data' => (object)[]
];
if(!empty($errorMessages)){
$response['data'] = $error;
}
return response()->json($response, $code);
}
}
create app/Http/Controllers/Api/ApiFunctionCallController.php
use Illuminate\Http\Request;
use App\Http\Controllers\Api\ApiCommanFunctionController as ApiCommanFunctionController;
use Validator;
use App\User;
use Auth;
class ApiFunctionCallController extends ApiCommanFunctionController
{
public function ApiUserregistration(Request $r){
$input = $r->all();
$rules = [
'name' => 'required',
'email' => 'required|email|checkEmailExitForUser',
'password' => 'required',
];
$message = [
'name.required' => "Name field is required.",
'email.required' => "Email field is required",
'email.check_email_exit_for_user' => "Email alredy exits.",
'password.required' => "Password field is required",
];
$validator = Validator::make($input,$rules,$message);
if ($validator->fails()) {
return app('App\Http\Controllers\Api\ApiCommanFunctionController')->sendError($validator->errors()->first(), $errorMessages = [], $code = 422);
}
$obj = new User;
$obj->name =$r->name;
$obj->email =$r->email;
$obj->password =\Hash::make($r->password);
$obj->save();
if ($obj !=null) {
return response()->json(['status' => 200,'msg'=>"User successfully register.",'data' => $obj ]);exit;
}else{
return response()->json(['status' => 204,'msg'=>"Somethinig is wrong or data not found",'data' => (object)[] ]);exit;
}
}
/**
* Get a JWT token via given credentials.
*
* @param \Illuminate\Http\Request $request
*
* @return \Illuminate\Http\JsonResponse
*/
public function login(Request $request)
{
$input = $request->all();
$rules = [
'email' => 'required|email',
'password' => 'required',
];
$message = [
'email.required' => "Email field is required",
'password.required' => "Password field is required",
];
$validator = Validator::make($input,$rules,$message);
if ($validator->fails()) {
return app('App\Http\Controllers\Api\ApiCommanFunctionController')->sendError($validator->errors()->first(), $errorMessages = [], $code = 422);
}
$credentials = $request->only('email', 'password');
if ($token = $this->guard()->attempt($credentials)) {
return $this->respondWithToken($token);
}
return response()->json(['status' => 404,'msg'=>"error",'data' => (object)[] ]);exit;
}
/**
* Get the authenticated User
*
* @return \Illuminate\Http\JsonResponse
*/
public function me()
{
return response()->json($this->guard()->user());
}
/**
* Log the user out (Invalidate the token)
*
* @return \Illuminate\Http\JsonResponse
*/
public function logout()
{
$this->guard()->logout();
return response()->json(['message' => 'Successfully logged out']);
}
/**
* Refresh a token.
*
* @return \Illuminate\Http\JsonResponse
*/
public function refresh()
{
return $this->respondWithToken($this->guard()->refresh());
}
/**
* Get the token array structure.
*
* @param string $token
*
* @return \Illuminate\Http\JsonResponse
*/
protected function respondWithToken($token)
{
return response()->json([
'access_token' => $token,
'token_type' => 'bearer',
'expires_in' => $this->guard()->factory()->getTTL() * 60
]);
}
/**
* Get the guard to be used during authentication.
*
* @return \Illuminate\Contracts\Auth\Guard
*/
public function guard()
{
return Auth::guard();
}
}
Now project configuration are ready to run our project.add blow code your project.
php artisan serve
Here is Routes URL List that we have created in this example.
1) Login: Method:POST, URL:http://localhost:8000/api/api-user-login
2) Register: Method:POST, URL:http://localhost:8000/api/api-user-registration
Register API:
Login API:
NOTE:- If you have any query or want to ask any question add your comment in below comment section.
Thank you.