Auth API implemented using JWT tokens, removed laravel passport

This commit is contained in:
prashant-webkul 2018-11-19 17:04:13 +05:30
parent 14997d6e97
commit ab9328d755
18 changed files with 474 additions and 108 deletions

View File

@ -1,27 +0,0 @@
<?php
namespace App\Criteria;
use Prettus\Repository\Contracts\CriteriaInterface;
use Prettus\Repository\Contracts\RepositoryInterface;
/**
* Class MyCriteria.
*
* @package namespace App\Criteria;
*/
class MyCriteria implements CriteriaInterface
{
/**
* Apply criteria in query repository
*
* @param string $model
* @param RepositoryInterface $repository
*
* @return mixed
*/
public function apply($model, RepositoryInterface $repository)
{
return $model;
}
}

View File

@ -18,7 +18,6 @@ class Kernel extends HttpKernel
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \App\Http\Middleware\PassportCustomProviderAccessToken::class
];
/**
@ -56,6 +55,5 @@ class Kernel extends HttpKernel
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
// 'passport-admin' => \App\Http\Middleware\CustomPassportProvider::class,
];
}

View File

@ -22,6 +22,6 @@ class AppServiceProvider extends ServiceProvider
*/
public function register()
{
//
}
}

View File

@ -2,8 +2,6 @@
namespace App\Providers;
use Illuminate\Support\Facades\Route;
use Laravel\Passport\Passport;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
@ -26,10 +24,5 @@ class AuthServiceProvider extends ServiceProvider
public function boot()
{
$this->registerPolicies();
Passport::routes();
// Route::group(['middleware' => 'passport-admin'], function () {
// Passport::routes();
// });
}
}

View File

@ -18,11 +18,11 @@
"kalnoy/nestedset": "^4.3",
"konekt/concord": "^1.2",
"laravel/framework": "5.6.*",
"laravel/passport": "^8.0@dev",
"laravel/tinker": "^1.0",
"nwidart/laravel-modules": "^3.2",
"prettus/l5-repository": "^2.6",
"propaganistas/laravel-intl": "^2.0"
"propaganistas/laravel-intl": "^2.0",
"tymon/jwt-auth": "dev-develop"
},
"require-dev": {
"barryvdh/laravel-debugbar": "^3.1",

View File

@ -199,6 +199,7 @@ return [
Konekt\Concord\ConcordServiceProvider::class,
Flynsarmy\DbBladeCompiler\DbBladeCompilerServiceProvider::class,
Barryvdh\DomPDF\ServiceProvider::class,
Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
//Webkul packages
Webkul\Theme\Providers\ThemeServiceProvider::class,
@ -272,6 +273,7 @@ return [
'Cart' => Webkul\Checkout\Facades\Cart::class,
'Core' => Webkul\Core\Facades\Core::class,
'DbView' => Flynsarmy\DbBladeCompiler\Facades\DbView::class,
'PDF' => Barryvdh\DomPDF\Facade::class
'PDF' => Barryvdh\DomPDF\Facade::class,
'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
],
];

View File

@ -13,7 +13,7 @@ return [
],
'api' => [
'driver' => 'passport',
'driver' => 'jwt',
'provider' => 'customers',
],
@ -27,10 +27,10 @@ return [
'provider' => 'admins'
],
// 'admin-api' => [
// 'driver' => 'token',
// 'provider' => 'admins',
// ]
'admin-api' => [
'driver' => 'jwt',
'provider' => 'admins',
]
],
'providers' => [

173
config/jwt.php Normal file
View File

@ -0,0 +1,173 @@
<?php
/*
* This file is part of jwt-auth.
*
* (c) Sean Tymon <tymon148@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
return [
/*
|--------------------------------------------------------------------------
| JWT Authentication Secret
|--------------------------------------------------------------------------
|
| Don't forget to set this, as it will be used to sign your tokens.
| A helper command is provided for this: `php artisan jwt:generate`
|
*/
'secret' => env('JWT_SECRET', 'changeme'),
/*
|--------------------------------------------------------------------------
| JWT time to live
|--------------------------------------------------------------------------
|
| Specify the length of time (in minutes) that the token will be valid for.
| Defaults to 1 hour
|
*/
'ttl' => env('JWT_TTL', 120),
/*
|--------------------------------------------------------------------------
| Refresh time to live
|--------------------------------------------------------------------------
|
| Specify the length of time (in minutes) that the token can be refreshed
| within. I.E. The user can refresh their token within a 2 week window of
| the original token being created until they must re-authenticate.
| Defaults to 2 weeks
|
*/
'refresh_ttl' => env('JWT_REFRESH_TTL', 86400),
/*
|--------------------------------------------------------------------------
| JWT hashing algorithm
|--------------------------------------------------------------------------
|
| Specify the hashing algorithm that will be used to sign the token.
|
| See here: https://github.com/namshi/jose/tree/2.2.0/src/Namshi/JOSE/Signer
| for possible values
|
*/
'algo' => 'HS256',
/*
|--------------------------------------------------------------------------
| User Model namespace
|--------------------------------------------------------------------------
|
| Specify the full namespace to your User model.
| e.g. 'Acme\Entities\User'
|
*/
'user' => 'App\User',
/*
|--------------------------------------------------------------------------
| User identifier
|--------------------------------------------------------------------------
|
| Specify a unique property of the user that will be added as the 'sub'
| claim of the token payload.
|
*/
'identifier' => 'id',
/*
|--------------------------------------------------------------------------
| Required Claims
|--------------------------------------------------------------------------
|
| Specify the required claims that must exist in any token.
| A TokenInvalidException will be thrown if any of these claims are not
| present in the payload.
|
*/
'required_claims' => ['iss', 'iat', 'exp', 'nbf', 'sub', 'jti'],
/*
|--------------------------------------------------------------------------
| Blacklist Enabled
|--------------------------------------------------------------------------
|
| In order to invalidate tokens, you must have the blacklist enabled.
| If you do not want or need this functionality, then set this to false.
|
*/
'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true),
/*
|--------------------------------------------------------------------------
| Providers
|--------------------------------------------------------------------------
|
| Specify the various providers used throughout the package.
|
*/
'providers' => [
/*
|--------------------------------------------------------------------------
| User Provider
|--------------------------------------------------------------------------
|
| Specify the provider that is used to find the user based
| on the subject claim
|
*/
'user' => 'Tymon\JWTAuth\Providers\User\EloquentUserAdapter',
/*
|--------------------------------------------------------------------------
| JWT Provider
|--------------------------------------------------------------------------
|
| Specify the provider that is used to create and decode the tokens.
|
*/
'jwt' => 'Tymon\JWTAuth\Providers\JWT\Namshi',
/*
|--------------------------------------------------------------------------
| Authentication Provider
|--------------------------------------------------------------------------
|
| Specify the provider that is used to authenticate users.
|
*/
'auth' => 'Tymon\JWTAuth\Providers\Auth\Illuminate',
/*
|--------------------------------------------------------------------------
| Storage Provider
|--------------------------------------------------------------------------
|
| Specify the provider that is used to store tokens in the blacklist
|
*/
'storage' => 'Tymon\JWTAuth\Providers\Storage\Illuminate'
],
];

View File

@ -0,0 +1,37 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAdminOauthTokensTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('admin_oauth_tokens', function (Blueprint $table) {
$table->increments('id');
$table->integer('admin_id')->unsigned();
$table->foreign('admin_id')->references('id')->on('admins');
$table->integer('throttle')->default(0)->unsigned();
$table->mediumText('api_token')->nullable();
$table->string('token_name')->nullable();
$table->dateTime('ttl');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('admin_oauth_tokens');
}
}

View File

@ -0,0 +1,37 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCustomerOauthTokensTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('customer_oauth_tokens', function (Blueprint $table) {
$table->increments('id');
$table->integer('customer_id')->unsigned();
$table->foreign('customer_id')->references('id')->on('customers');
$table->integer('throttle')->default(0)->unsigned();
$table->mediumText('api_token')->nullable();
$table->string('token_name')->nullable();
$table->dateTime('ttl');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('customer_oauth_tokens');
}
}

View File

@ -6,7 +6,7 @@ use Webkul\API\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Event;
use Webkul\User\Models\Admin;
use Webkul\User\Repositories\AdminRepository;
/**
* Session controller for the APIs of user admins
@ -16,6 +16,19 @@ use Webkul\User\Models\Admin;
*/
class AuthController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
protected $_config;
public function __construct()
{
$this->middleware('admin')->except(['show','create']);
$this->_config = request('_config');
}
public function create(Request $request)
{
$request->validate([
@ -23,18 +36,68 @@ class AuthController extends Controller
'password' => 'required'
]);
if (!auth()->guard('admin')->attempt(request(['email', 'password']))) {
return response()->json(false, 200);
$credentials['email'] = $request->input('email');
$credentials['password'] = $request->input('password');
if ($token = $this->guard()->attempt(request(['email', 'password']))) {
return $this->respondWithToken($token);
}
if(auth()->guard('admin')->check()) {
$admin = auth()->guard('admin')->user();
return response()->json(['error' => 'Unauthorized'], 401);
}
$token = $admin->createToken('admin-token')->accessToken;
/**
* 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' => auth('api')->factory()->getTTL() * 60,
'admin_id' => auth()->guard('admin-api')->user()->id,
'admin_email' => auth()->guard('admin-api')->user()->email
]);
}
return response()->json($token, 200);
} else {
return response()->json(false, 200);
}
/**
* Get the guard to be used during authentication.
*
* @return \Illuminate\Contracts\Auth\Guard
*/
public function guard()
{
return auth()->guard('admin-api');
}
/**
* Refresh a token.
*
* @return \Illuminate\Http\JsonResponse
*/
public function refresh()
{
return $this->respondWithToken($this->guard()->refresh());
}
/**
* Get the authenticated User
*
* @return \Illuminate\Http\JsonResponse
*/
public function me()
{
return response()->json($this->guard()->user());
}
public function destroy($id)
{
$this->guard()->logout();
return response()->json(['message' => 'Successfully logged out']);
}
}

View File

@ -6,8 +6,8 @@ use Webkul\API\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Event;
use Webkul\Customer\Models\Customer;
use Webkul\Customer\Http\Listeners\CustomerEventsHandler;
use Auth;
use Cart;
/**
@ -43,27 +43,68 @@ class AuthController extends Controller
'password' => 'required'
]);
if (!auth()->guard('customer')->attempt(request(['email', 'password']))) {
return response()->json([false], 200);
$credentials['email'] = $request->input('email');
$credentials['password'] = $request->input('password');
if ($token = $this->guard()->attempt(request(['email', 'password']))) {
return $this->respondWithToken($token);
}
if(auth()->guard('customer')->check()) {
$customer = auth()->guard('customer')->user();
return response()->json(['error' => 'Unauthorized'], 401);
}
$token = $customer->createToken('customer-token')->accessToken;
/**
* 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' => auth('api')->factory()->getTTL() * 60,
'customer_id' => auth()->guard('customer')->user()->id,
'customer_email' => auth()->guard('customer')->user()->email
]);
}
return response()->json([$token], 200);
} else {
return response()->json([false], 200);
}
/**
* Get the guard to be used during authentication.
*
* @return \Illuminate\Contracts\Auth\Guard
*/
public function guard()
{
return Auth::guard('api');
}
/**
* Refresh a token.
*
* @return \Illuminate\Http\JsonResponse
*/
public function refresh()
{
return $this->respondWithToken($this->guard()->refresh());
}
/**
* Get the authenticated User
*
* @return \Illuminate\Http\JsonResponse
*/
public function me()
{
return response()->json($this->guard()->user());
}
public function destroy($id)
{
auth()->guard('customer')->logout();
$this->guard()->logout();
Event::fire('customer.after.logout', $id);
return redirect()->route($this->_config['redirect']);
return response()->json(['message' => 'Successfully logged out']);
}
}
}

View File

@ -1,16 +1,15 @@
<?php
use Illuminate\Http\Request;
Route::prefix('api')->group(function () {
//customer APIs
Route::prefix('customer')->group(function () {
Route::post('login', 'Webkul\API\Http\Controllers\Customer\AuthController@create')->name('login');
});
//Admin APIs
Route::prefix('admin')->group(function () {
Route::post('login', 'Webkul\API\Http\Controllers\Admin\AuthController@create');
});
Route::group(['middleware' => 'api', 'namespace' => 'Webkul\API\Http\Controllers', 'prefix' => 'api/customer'], function ($router) {
Route::post('login', 'Customer\AuthController@create');
Route::post('logout', 'Customer\AuthController@destroy');
Route::post('refresh', 'Customer\AuthController@refresh');
Route::post('me', 'Customer\AuthController@me');
});
Route::group(['namespace' => 'Webkul\API\Http\Controllers', 'prefix' => 'api/admin'], function ($router) {
Route::post('login', 'Admin\AuthController@create');
Route::post('logout', 'Admin\AuthController@destroy');
Route::post('refresh', 'Admin\AuthController@refresh');
Route::post('me', 'Admin\AuthController@me');
});

View File

@ -14,6 +14,8 @@ class APIServiceProvider extends ServiceProvider
public function boot()
{
$this->loadRoutesFrom(__DIR__.'/../Http/api.php');
$this->loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
}
/**
@ -23,5 +25,20 @@ class APIServiceProvider extends ServiceProvider
*/
public function register()
{
// $app['Dingo\Api\Auth\Auth']->extend('oauth', function ($app) {
// return new Dingo\Api\Auth\Provider\JWT($app['Tymon\JWTAuth\JWTAuth']);
// });
// $app['Dingo\Api\Http\RateLimit\Handler']->extend(function ($app) {
// return new Dingo\Api\Http\RateLimit\Throttle\Authenticated;
// });
// $app['Dingo\Api\Transformer\Factory']->setAdapter(function ($app) {
// $fractal = new League\Fractal\Manager;
// $fractal->setSerializer(new League\Fractal\Serializer\JsonApiSerializer);
// return new Dingo\Api\Transformer\Adapter\Fractal($fractal);
// });
}
}

View File

@ -82,13 +82,6 @@ class CustomerDataGrid
'label' => 'Email',
'sortable' => false,
],
[
'name' => 'phone',
'alias' => 'Phone',
'type' => 'number',
'label' => 'Phone',
'sortable' => true,
],
[
'name' => 'customer_group_id',
'alias' => 'CustomerGroupId',

View File

@ -32,12 +32,12 @@ class OrderDataGrid
//True in case of joins else aliasing key required on all cases
'massoperations' =>[
[
'route' => route('admin.datagrid.delete'),
'method' => 'DELETE',
'label' => 'Delete',
'type' => 'button',
],
// [
// 'route' => route('admin.datagrid.delete'),
// 'method' => 'DELETE',
// 'label' => 'Delete',
// 'type' => 'button',
// ],
],
'actions' => [
@ -47,12 +47,12 @@ class OrderDataGrid
'confirm_text' => 'Do you really want to do this?',
'icon' => 'icon pencil-lg-icon',
],
[
'type' => 'Delete',
'route' => route('admin.datagrid.delete'),
'confirm_text' => 'Do you really want to do this?',
'icon' => 'icon trash-icon',
],
// [
// 'type' => 'Delete',
// 'route' => route('admin.datagrid.delete'),
// 'confirm_text' => 'Do you really want to do this?',
// 'icon' => 'icon trash-icon',
// ],
],
'join' => [],

View File

@ -2,7 +2,7 @@
namespace Webkul\Customer\Models;
use Laravel\Passport\HasApiTokens;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Webkul\Customer\Models\CustomerGroup;
@ -12,9 +12,9 @@ use Webkul\Customer\Models\Wishlist;
use Webkul\Customer\Notifications\CustomerResetPassword;
class Customer extends Authenticatable
class Customer extends Authenticatable implements JWTSubject
{
use HasApiTokens, Notifiable;
use Notifiable;
protected $table = 'customers';
@ -22,7 +22,27 @@ class Customer extends Authenticatable
protected $hidden = ['password', 'remember_token'];
/**
/**
* 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 [];
}
/**
* Get the customer full name.
*/
public function getNameAttribute() {

View File

@ -2,16 +2,16 @@
namespace Webkul\User\Models;
use Laravel\Passport\HasApiTokens;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Webkul\User\Models\Role;
use Webkul\User\Notifications\AdminResetPassword;
class Admin extends Authenticatable
class Admin extends Authenticatable implements JWTSubject
{
use HasApiTokens, Notifiable;
use Notifiable;
/**
* The attributes that are mass assignable.
@ -31,6 +31,26 @@ class Admin extends Authenticatable
'password', 'remember_token',
];
/**
* 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 [];
}
/**
* Get the role that owns the admin.
*/