Commit 0fc48c64 authored by Viral Solani's avatar Viral Solani

API Boilerplate

parent 1b4b4b6f
...@@ -33,7 +33,7 @@ class APIController extends Controller ...@@ -33,7 +33,7 @@ class APIController extends Controller
* *
* @param [type] $statusCode [description] * @param [type] $statusCode [description]
* *
* @return mix * @return statuscode
*/ */
public function setStatusCode($statusCode) public function setStatusCode($statusCode)
{ {
...@@ -42,37 +42,13 @@ class APIController extends Controller ...@@ -42,37 +42,13 @@ class APIController extends Controller
return $this; return $this;
} }
/**
* responsd not found.
*
* @param string $message
*
* @return mix
*/
public function respondNotFound($message = 'Not Found')
{
return $this->setStatusCode(IlluminateResponse::HTTP_NOT_FOUND)->respondWithError($message);
}
/**
* Respond with error.
*
* @param string $message
*
* @return mix
*/
public function respondInternalError($message = 'Internal Error')
{
return $this->setStatusCode('500')->respondWithError($message);
}
/** /**
* Respond. * Respond.
* *
* @param array $data * @param array $data
* @param array $headers * @param array $headers
* *
* @return mix * @return \Illuminate\Http\JsonResponse
*/ */
public function respond($data, $headers = []) public function respond($data, $headers = [])
{ {
...@@ -85,7 +61,7 @@ class APIController extends Controller ...@@ -85,7 +61,7 @@ class APIController extends Controller
* @param Paginator $items * @param Paginator $items
* @param array $data * @param array $data
* *
* @return mix * @return \Illuminate\Http\JsonResponse
*/ */
public function respondWithPagination($items, $data) public function respondWithPagination($items, $data)
{ {
...@@ -101,12 +77,38 @@ class APIController extends Controller ...@@ -101,12 +77,38 @@ class APIController extends Controller
return $this->respond($data); return $this->respond($data);
} }
/**
* Respond Created.
*
* @param string $message
*
* @return \Illuminate\Http\JsonResponse
*/
public function respondCreated($data)
{
return $this->setStatusCode(201)->respond([
'data' => $data,
]);
}
/**
* Respond Created with data.
*
* @param string $message
*
* @return \Illuminate\Http\JsonResponse
*/
public function respondCreatedWithData($data)
{
return $this->setStatusCode(201)->respond($data);
}
/** /**
* respond with error. * respond with error.
* *
* @param $message * @param $message
* *
* @return mix * @return \Illuminate\Http\JsonResponse
*/ */
public function respondWithError($message) public function respondWithError($message)
{ {
...@@ -119,17 +121,61 @@ class APIController extends Controller ...@@ -119,17 +121,61 @@ class APIController extends Controller
} }
/** /**
* Respond Created. * responsd not found.
* *
* @param string $message * @param string $message
* *
* @return mix * @return \Illuminate\Http\JsonResponse
*/ */
public function respondCreated($message) public function respondNotFound($message = 'Not Found')
{ {
return $this->setStatusCode(201)->respond([ return $this->setStatusCode(IlluminateResponse::HTTP_NOT_FOUND)->respondWithError($message);
'message' => $message, }
]);
/**
* Respond with error.
*
* @param string $message
*
* @return \Illuminate\Http\JsonResponse
*/
public function respondInternalError($message = 'Internal Error')
{
return $this->setStatusCode(500)->respondWithError($message);
}
/**
* Respond with unauthorized.
*
* @param string $message
*
* @return \Illuminate\Http\JsonResponse
*/
protected function respondUnauthorized($message = 'Unauthorized')
{
return $this->setStatusCode(401)->respondWithError($message);
}
/**
* Respond with forbidden.
*
* @param string $message
*
* @return \Illuminate\Http\JsonResponse
*/
protected function respondForbidden($message = 'Forbidden')
{
return $this->setStatusCode(403)->respondWithError($message);
}
/**
* Respond with no content.
*
* @return \Illuminate\Http\JsonResponse
*/
protected function respondWithNoContent()
{
return $this->setStatusCode(204)->respond(null);
} }
/** /**
......
...@@ -2,74 +2,49 @@ ...@@ -2,74 +2,49 @@
namespace App\Http\Controllers\Api\V1; namespace App\Http\Controllers\Api\V1;
use App\Models\Access\User\User;
use App\Notifications\Activated;
use App\Notifications\Activation;
use App\Notifications\PasswordReset;
use App\Notifications\PasswordResetted;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use JWTAuth; use JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException; use Tymon\JWTAuth\Exceptions\JWTException;
use Validator; use Validator;
/**
* AuthController.
*/
class AuthController extends APIController class AuthController extends APIController
{ {
/** /**
* Authenticate User. * Log the user in.
* *
* @param Request $request * @param Request $request
* *
* @return \Illuminate\Http\JsonResponse * @return \Illuminate\Http\JsonResponse
*/ */
public function authenticate(Request $request) public function login(Request $request)
{ {
$credentials = $request->only('email', 'password'); $validation = Validator::make($request->all(), [
'email' => 'required|email',
try { 'password' => 'required|min:4',
if (!$token = JWTAuth::attempt($credentials)) { ]);
return $this->throwValidation('Invalid Credentials! Please try again.');
}
} catch (JWTException $e) {
return $this->respondInternalError('This is something wrong. Please try again!');
}
$user = User::whereEmail(request('email'))->first();
if ($user->status != 1) { if ($validation->fails()) {
return $this->throwValidation('Your account hasn\'t been activated. Please check your email & activate account.'); return $this->throwValidation($validation->messages()->first());
} }
return $this->respond([ $credentials = $request->only(['email', 'password']);
'message' => 'You are successfully logged in!',
'token' => $token,
]);
}
/**
* Check if user is authenticated or not.
*
* @return \Illuminate\Http\JsonResponse
*/
public function check()
{
try { try {
JWTAuth::parseToken()->authenticate(); if (!$token = JWTAuth::attempt($credentials)) {
return $this->throwValidation(trans('api.messages.login.failed'));
}
} catch (JWTException $e) { } catch (JWTException $e) {
return $this->respond([ return $this->respondInternalError($e->getMessage());
'authenticated' => false,
]);
} }
return $this->respond([ return $this->respond([
'authenticated' => true, 'message' => trans('api.messages.login.success'),
'token' => $token,
]); ]);
} }
/** /**
* Log Out. * Log the user out (Invalidate the token).
* *
* @return \Illuminate\Http\JsonResponse * @return \Illuminate\Http\JsonResponse
*/ */
...@@ -82,190 +57,36 @@ class AuthController extends APIController ...@@ -82,190 +57,36 @@ class AuthController extends APIController
JWTAuth::invalidate($token); JWTAuth::invalidate($token);
} }
} catch (JWTException $e) { } catch (JWTException $e) {
return $this->respondInternalError('This is something wrong. Please try again!'); return $this->respondInternalError($e->getMessage());
} }
return $this->respond([ return $this->respond([
'message' => 'You are successfully logged out!', 'message' => trans('api.messages.logout.success'),
]);
}
/**
* Register User.
*
* @param Request $request
*
* @return \Illuminate\Http\JsonResponse
*/
public function register(Request $request)
{
$validation = Validator::make($request->all(), [
'first_name' => 'required',
'last_name' => 'required',
'email' => 'required|email|unique:users',
'password' => 'required|min:6',
'password_confirmation' => 'required|same:password',
]);
if ($validation->fails()) {
return $this->throwValidation($validation->messages()->first());
}
$user = User::create([
'first_name' => request('first_name'),
'last_name' => request('last_name'),
'email' => request('email'),
'status' => '0',
'password' => bcrypt(request('password')),
'country_id' => 1,
'state_id' => 1,
'city_id' => 1,
'zip_code' => 1,
'ssn' => 123456789,
'created_by' => 1,
]);
$user->confirmation_code = generateUuid();
$user->save();
$user->notify(new Activation($user));
return $this->respondCreated([
'You have registered successfully. Please check your email for activation!',
]); ]);
} }
/** /**
* Activate User. * Refresh a token.
*
* @param $activation_token [description]
* *
* @return \Illuminate\Http\JsonResponse * @return \Illuminate\Http\JsonResponse
*/ */
public function activate($activation_token) public function refresh()
{ {
$user = User::whereConfirmationCode($activation_token)->first(); $token = JWTAuth::getToken();
if (!$user) { if (!$token) {
return $this->throwValidation('Invalid activation token!'); $this->respondUnauthorized(trans('api.messages.refresh.token.not_provided'));
} }
if ($user->status == 1) { try {
return $this->throwValidation('Your account has already been activated!'); $refreshedToken = JWTAuth::refresh($token);
} catch (JWTException $e) {
return $this->respondInternalError($e->getMessage());
} }
$user->confirmed = 1;
$user->status = 1;
$user->save();
$user->notify(new Activated($user));
return $this->respond([ return $this->respond([
'message' => 'Your account has been activated!', 'status' => trans('api.messages.refresh.status'),
]); 'token' => $refreshedToken,
}
public function password(Request $request)
{
$validation = Validator::make($request->all(), [
'email' => 'required|email',
]);
if ($validation->fails()) {
return response()->json(['message' => $validation->messages()->first()], 422);
}
$user = User::whereEmail(request('email'))->first();
if (!$user) {
return response()->json(['message' => 'We couldn\'t found any user with this email. Please try again!'], 422);
}
$token = generateUuid();
\DB::table('password_resets')->insert([
'email' => request('email'),
'token' => $token,
]);
$user->notify(new PasswordReset($user, $token));
return response()->json(['message' => 'We have sent reminder email. Please check your inbox!']);
}
public function validatePasswordReset(Request $request)
{
$validate_password_request = \DB::table('password_resets')->where('token', '=', request('token'))->first();
if (!$validate_password_request) {
return response()->json(['message' => 'Invalid password reset token!'], 422);
}
if (date('Y-m-d H:i:s', strtotime($validate_password_request->created_at.'+30 minutes')) < date('Y-m-d H:i:s')) {
return response()->json(['message' => 'Password reset token is expired. Please request reset password again!'], 422);
}
return response()->json(['message' => '']);
}
public function reset(Request $request)
{
$validation = Validator::make($request->all(), [
'email' => 'required|email',
'password' => 'required|min:6',
'password_confirmation' => 'required|same:password',
]);
if ($validation->fails()) {
return response()->json(['message' => $validation->messages()->first()], 422);
}
$user = User::whereEmail(request('email'))->first();
if (!$user) {
return response()->json(['message' => 'We couldn\'t found any user with this email. Please try again!'], 422);
}
$validate_password_request = \DB::table('password_resets')->where('email', '=', request('email'))->where('token', '=', request('token'))->first();
if (!$validate_password_request) {
return response()->json(['message' => 'Invalid password reset token!'], 422);
}
if (date('Y-m-d H:i:s', strtotime($validate_password_request->created_at.'+30 minutes')) < date('Y-m-d H:i:s')) {
return response()->json(['message' => 'Password reset token is expired. Please request reset password again!'], 422);
}
$user->password = bcrypt(request('password'));
$user->save();
$user->notify(new PasswordResetted($user));
return response()->json(['message' => 'Your password has been reset. Please login again!']);
}
public function changePassword(Request $request)
{
if (env('IS_DEMO')) {
return response()->json(['message' => 'You are not allowed to perform this action in this mode.'], 422);
}
$validation = Validator::make($request->all(), [
'current_password' => 'required',
'new_password' => 'required|confirmed|different:current_password|min:6',
'new_password_confirmation' => 'required|same:new_password',
]); ]);
if ($validation->fails()) {
return response()->json(['message' => $validation->messages()->first()], 422);
}
$user = JWTAuth::parseToken()->authenticate();
if (!\Hash::check(request('current_password'), $user->password)) {
return response()->json(['message' => 'Old password does not match! Please try again!'], 422);
}
$user->password = bcrypt(request('new_password'));
$user->save();
return response()->json(['message' => 'Your password has been changed successfully!']);
} }
} }
<?php
namespace App\Http\Controllers\Api\V1;
use Validator;
use App\Models\User\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Repositories\UserRepository;
use Illuminate\Support\Facades\Password;
use App\Notifications\UserNeedsPasswordReset;
class ForgotPasswordController extends APIController
{
/**
* __construct.
*
* @param $repository
*/
public function __construct(UserRepository $repository)
{
$this->repository = $repository;
}
/**
* Send a reset link to the given user.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function sendResetLinkEmail(Request $request)
{
$validation = Validator::make($request->all(), [
'email' => 'required|email',
]);
if ($validation->fails()) {
return $this->throwValidation($validation->messages()->first());
}
$user = $this->repository->getUserByEmail($request);
if(!$user) {
return $this->respondNotFound(trans('api.messages.forgot_password.validation.email_not_found'));
}
$token = $this->repository->createNewToken();
$user->notify(new UserNeedsPasswordReset($token));
return $this->respond([
'status' => 'ok',
'message' => trans('api.messages.forgot_password.success'),
]);
}
}
<?php
namespace App\Http\Controllers\Api\V1;
use Config;
use JWTAuth;
use Validator;
use App\Models\User\User;
use Illuminate\Http\Request;
use App\Repositories\Frontend\Access\User\UserRepository;
class RegisterController extends APIController
{
protected $repository;
/**
* __construct.
*
* @param $repository
*/
public function __construct(UserRepository $repository)
{
$this->repository = $repository;
}
/**
* Register User.
*
* @param Request $request
*
* @return \Illuminate\Http\JsonResponse
*/
public function register(Request $request)
{
$validation = Validator::make($request->all(), [
'first_name' => 'required',
'last_name' => 'required',
'email' => 'required|email|unique:users',
'password' => 'required|min:4',
'password_confirmation' => 'required|same:password',
'is_term_accept' => 'required'
]);
if ($validation->fails()) {
return $this->throwValidation($validation->messages()->first());
}
$user = $this->repository->create($request->all());
if (!Config::get('api.register.release_token')) {
return $this->respondCreated([
'message' => trans('api.messages.registeration.success'),
]);
}
$token = JWTAuth::fromUser($user);
return $this->respondCreated([
'message' => trans('api.messages.registeration.success'),
'token' => $token,
]);
}
}
<?php
namespace App\Http\Controllers\Api\V1;
use Validator;
use App\Models\User\User;
use Illuminate\Http\Request;
use App\Http\Resources\UserResource;
use App\Repositories\Backend\Access\User\UserRepository;
class UsersController extends APIController
{
protected $repository;
/**
* __construct.
*
* @param $repository
*/
public function __construct(UserRepository $repository)
{
$this->repository = $repository;
}
/**
* Return the users.
*
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
$limit = $request->get('paginate') ? $request->get('paginate') : 25;
return UserResource::collection(
$this->repository->getPaginated($limit)
);
}
/**
* Return the specified resource.
*
* @param User $user
*
* @return \Illuminate\Http\Response
*/
public function show(User $user)
{
return new UserResource($user);
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, User $user)
{
$validation = Validator::make($request->all(), [
'name' => 'required',
'email' => 'email|unique:users,email,'.$user->id,
'password' => 'nullable|confirmed',
]);
if ($validation->fails()) {
return $this->throwValidation($validation->messages()->first());
}
$user = $this->repository->update($user->id, $request->all());
return new UserResource($user);
}
}
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
namespace App\Http; namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel; use Illuminate\Foundation\Http\Kernel as HttpKernel;
use Tymon\JWTAuth\Middleware\GetUserFromToken;
use Tymon\JWTAuth\Middleware\RefreshToken;
/** /**
* Class Kernel. * Class Kernel.
...@@ -73,8 +75,7 @@ class Kernel extends HttpKernel ...@@ -73,8 +75,7 @@ class Kernel extends HttpKernel
*/ */
'access.routeNeedsRole' => \App\Http\Middleware\RouteNeedsRole::class, 'access.routeNeedsRole' => \App\Http\Middleware\RouteNeedsRole::class,
'access.routeNeedsPermission' => \App\Http\Middleware\RouteNeedsPermission::class, 'access.routeNeedsPermission' => \App\Http\Middleware\RouteNeedsPermission::class,
//'jwt.auth' => \App\Http\Middleware\VerifyJWTToken::class, 'jwt.auth' => GetUserFromToken::class,
'jwt.auth' => \Tymon\JWTAuth\Middleware\GetUserFromToken::class, 'jwt.refresh' => RefreshToken::class,
'jwt.refresh' => \Tymon\JWTAuth\Middleware\RefreshToken::class,
]; ];
} }
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\Resource;
class UserResource extends Resource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request
*
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'registered_at' => $this->created_at->toIso8601String(),
];
}
}
...@@ -9,12 +9,13 @@ use App\Models\Access\User\Traits\UserAccess; ...@@ -9,12 +9,13 @@ use App\Models\Access\User\Traits\UserAccess;
use App\Models\Access\User\Traits\UserSendPasswordReset; use App\Models\Access\User\Traits\UserSendPasswordReset;
use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Foundation\Auth\User as Authenticatable;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Notifications\Notifiable; use Illuminate\Notifications\Notifiable;
/** /**
* Class User. * Class User.
*/ */
class User extends Authenticatable class User extends Authenticatable implements JWTSubject
{ {
use UserScope, use UserScope,
UserAccess, UserAccess,
...@@ -67,4 +68,24 @@ class User extends Authenticatable ...@@ -67,4 +68,24 @@ class User extends Authenticatable
parent::__construct($attributes); parent::__construct($attributes);
$this->table = config('access.users_table'); $this->table = config('access.users_table');
} }
/**
* 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 [];
}
} }
...@@ -15,6 +15,28 @@ class BaseRepository ...@@ -15,6 +15,28 @@ class BaseRepository
return $this->query()->get(); return $this->query()->get();
} }
/**
* Get Paginated.
*
* @param $per_page
* @param string $active
* @param string $order_by
* @param string $sort
*
* @return mixed
*/
public function getPaginated($per_page, $active = '', $order_by = 'id', $sort = 'asc')
{
if ($active) {
return $this->query()->where('status', $active)
->orderBy($order_by, $sort)
->paginate($per_page);
} else {
return $this->query()->orderBy($order_by, $sort)
->paginate($per_page);
}
}
/** /**
* @return mixed * @return mixed
*/ */
......
...@@ -95,7 +95,6 @@ class UserRepository extends BaseRepository ...@@ -95,7 +95,6 @@ class UserRepository extends BaseRepository
$user->password = $provider ? null : bcrypt($data['password']); $user->password = $provider ? null : bcrypt($data['password']);
$user->confirmed = $provider ? 1 : (config('access.users.confirm_email') ? 0 : 1); $user->confirmed = $provider ? 1 : (config('access.users.confirm_email') ? 0 : 1);
$user->is_term_accept = $data['is_term_accept']; $user->is_term_accept = $data['is_term_accept'];
$user->created_by = 1;
DB::transaction(function () use ($user) { DB::transaction(function () use ($user) {
if ($user->save()) { if ($user->save()) {
......
This diff is collapsed.
<?php <?php
return [ return [
/* // these options are related to the sign-up procedure
|-------------------------------------------------------------------------- 'register' => [
| Standards Tree
|--------------------------------------------------------------------------
|
| Versioning an API with Dingo revolves around content negotiation and
| custom MIME types. A custom type will belong to one of three
| standards trees, the Vendor tree (vnd), the Personal tree
| (prs), and the Unregistered tree (x).
|
| By default the Unregistered tree (x) is used, however, should you wish
| to you can register your type with the IANA. For more details:
| https://tools.ietf.org/html/rfc6838
|
*/
'standardsTree' => env('API_STANDARDS_TREE', 'x'),
/*
|--------------------------------------------------------------------------
| API Subtype
|--------------------------------------------------------------------------
|
| Your subtype will follow the standards tree you use when used in the
| "Accept" header to negotiate the content type and version.
|
| For example: Accept: application/x.SUBTYPE.v1+json
|
*/
'subtype' => env('API_SUBTYPE', ''),
/*
|--------------------------------------------------------------------------
| Default API Version
|--------------------------------------------------------------------------
|
| This is the default version when strict mode is disabled and your API
| is accessed via a web browser. It's also used as the default version
| when generating your APIs documentation.
|
*/
'version' => env('API_VERSION', 'v1'),
/*
|--------------------------------------------------------------------------
| Default API Prefix
|--------------------------------------------------------------------------
|
| A default prefix to use for your API routes so you don't have to
| specify it for each group.
|
*/
'prefix' => env('API_PREFIX', null),
/*
|--------------------------------------------------------------------------
| Default API Domain
|--------------------------------------------------------------------------
|
| A default domain to use for your API routes so you don't have to
| specify it for each group.
|
*/
'domain' => env('API_DOMAIN', null),
/*
|--------------------------------------------------------------------------
| Name
|--------------------------------------------------------------------------
|
| When documenting your API using the API Blueprint syntax you can
| configure a default name to avoid having to manually specify
| one when using the command.
|
*/
'name' => env('API_NAME', null),
/*
|--------------------------------------------------------------------------
| Conditional Requests
|--------------------------------------------------------------------------
|
| Globally enable conditional requests so that an ETag header is added to
| any successful response. Subsequent requests will perform a check and
| will return a 304 Not Modified. This can also be enabled or disabled
| on certain groups or routes.
|
*/
'conditionalRequest' => env('API_CONDITIONAL_REQUEST', true),
/*
|--------------------------------------------------------------------------
| Strict Mode
|--------------------------------------------------------------------------
|
| Enabling strict mode will require clients to send a valid Accept header
| with every request. This also voids the default API version, meaning
| your API will not be browsable via a web browser.
|
*/
'strict' => env('API_STRICT', false),
/*
|--------------------------------------------------------------------------
| Debug Mode
|--------------------------------------------------------------------------
|
| Enabling debug mode will result in error responses caused by thrown
| exceptions to have a "debug" key that will be populated with
| more detailed information on the exception.
|
*/
'debug' => env('API_DEBUG', false),
/*
|--------------------------------------------------------------------------
| Generic Error Format
|--------------------------------------------------------------------------
|
| When some HTTP exceptions are not caught and dealt with the API will
| generate a generic error response in the format provided. Any
| keys that aren't replaced with corresponding values will be
| removed from the final response.
|
*/
'errorFormat' => [
'message' => ':message',
'errors' => ':errors',
'code' => ':code',
'status_code' => ':status_code',
'debug' => ':debug',
],
/*
|--------------------------------------------------------------------------
| API Middleware
|--------------------------------------------------------------------------
|
| Middleware that will be applied globally to all API requests.
|
*/
'middleware' => [
// this option must be set to true if you want to release a token
// when your user successfully terminates the sign-in procedure
'release_token' => env('SIGN_UP_RELEASE_TOKEN', true),
], ],
/* // these options are related to the password recovery procedure
|-------------------------------------------------------------------------- 'reset_password' => [
| Authentication Providers
|--------------------------------------------------------------------------
|
| The authentication providers that should be used when attempting to
| authenticate an incoming API request.
|
*/
'auth' => [
'jwt' => 'Dingo\Api\Auth\Provider\JWT',
],
/*
|--------------------------------------------------------------------------
| Throttling / Rate Limiting
|--------------------------------------------------------------------------
|
| Consumers of your API can be limited to the amount of requests they can
| make. You can create your own throttles or simply change the default
| throttles.
|
*/
'throttling' => [
],
/*
|--------------------------------------------------------------------------
| Response Transformer
|--------------------------------------------------------------------------
|
| Responses can be transformed so that they are easier to format. By
| default a Fractal transformer will be used to transform any
| responses prior to formatting. You can easily replace
| this with your own transformer.
|
*/
'transformer' => env('API_TRANSFORMER', Dingo\Api\Transformer\Adapter\Fractal::class),
/*
|--------------------------------------------------------------------------
| Response Formats
|--------------------------------------------------------------------------
|
| Responses can be returned in multiple formats by registering different
| response formatters. You can also customize an existing response
| formatter.
|
*/
'defaultFormat' => env('API_DEFAULT_FORMAT', 'json'),
'formats' => [
'json' => Dingo\Api\Http\Response\Format\Json::class,
// this option must be set to true if you want to release a token
// when your user successfully terminates the password reset procedure
'release_token' => env('PASSWORD_RESET_RELEASE_TOKEN', false),
], ],
]; ];
<?php
return [
/*
* Validation rules for all api.
*/
'login' => [
'rules' => [
'email' => 'required|email',
'password' => 'required',
],
],
'forgotpassword' => [
'rules' => [
'email' => 'required|email',
],
],
'resetpassword' => [
'rules' => [
'email' => 'required|email',
'password_confirmation' => 'required',
'password' => 'required|confirmed',
'token' => 'required',
],
],
'register' => [
'rules' => [
'first_name' => 'required|max:255',
'last_name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|min:6|confirmed',
'state_id' => 'required',
'city_id' => 'required',
'zip_code' => 'required',
'ssn' => 'required',
],
],
'confirmaccount' => [
'rules' => [
'email' => 'required|email',
'otp' => 'required',
],
],
];
...@@ -44,7 +44,7 @@ return [ ...@@ -44,7 +44,7 @@ return [
], ],
'api' => [ 'api' => [
'driver' => 'token', 'driver' => 'jwt',
'provider' => 'users', 'provider' => 'users',
], ],
], ],
......
...@@ -16,76 +16,124 @@ return [ ...@@ -16,76 +16,124 @@ return [
| JWT Authentication Secret | JWT Authentication Secret
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| |
| Don't forget to set this, as it will be used to sign your tokens. | Don't forget to set this in your .env file, as it will be used to sign
| A helper command is provided for this: `php artisan jwt:generate` | your tokens. A helper command is provided for this:
| `php artisan jwt:secret`
|
| Note: This will be used for Symmetric algorithms only (HMAC),
| since RSA and ECDSA use a private/public key combo (See below).
| |
*/ */
'secret' => env('JWT_SECRET', '3M0tGfsEolZsrst5wrJgUOWk5Zkqzx5A'), 'secret' => env('JWT_SECRET'),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| JWT time to live | JWT Authentication Keys
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| |
| Specify the length of time (in minutes) that the token will be valid for. | The algorithm you are using, will determine whether your tokens are
| Defaults to 1 hour | signed with a random string (defined in `JWT_SECRET`) or using the
| following public & private keys.
|
| Symmetric Algorithms:
| HS256, HS384 & HS512 will use `JWT_SECRET`.
|
| Asymmetric Algorithms:
| RS256, RS384 & RS512 / ES256, ES384 & ES512 will use the keys below.
| |
*/ */
'ttl' => 60, 'keys' => [
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Refresh time to live | Public Key
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| |
| Specify the length of time (in minutes) that the token can be refreshed | A path or resource to your public key.
| 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. | E.g. 'file://path/to/public/key'
| Defaults to 2 weeks
| |
*/ */
'refresh_ttl' => 20160, 'public' => env('JWT_PUBLIC_KEY'),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| JWT hashing algorithm | Private Key
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| |
| Specify the hashing algorithm that will be used to sign the token. | A path or resource to your private key.
|
| E.g. 'file://path/to/private/key'
|
*/
'private' => env('JWT_PRIVATE_KEY'),
/*
|--------------------------------------------------------------------------
| Passphrase
|--------------------------------------------------------------------------
|
| The passphrase for your private key. Can be null if none set.
|
*/
'passphrase' => env('JWT_PASSPHRASE'),
],
/*
|--------------------------------------------------------------------------
| JWT time to live
|--------------------------------------------------------------------------
|
| Specify the length of time (in minutes) that the token will be valid for.
| Defaults to 1 hour.
| |
| See here: https://github.com/namshi/jose/tree/2.2.0/src/Namshi/JOSE/Signer | You can also set this to null, to yield a never expiring token.
| for possible values | Some people may want this behaviour for e.g. a mobile app.
| This is not particularly recommended, so make sure you have appropriate
| systems in place to revoke the token if necessary.
| |
*/ */
'algo' => 'HS256', 'ttl' => env('JWT_TTL', 60),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| User Model namespace | Refresh time to live
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| |
| Specify the full namespace to your User model. | Specify the length of time (in minutes) that the token can be refreshed
| e.g. 'Acme\Entities\User' | 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.
|
| You can also set this to null, to yield an infinite refresh time.
| Some may want this instead of never expiring tokens for e.g. a mobile app.
| This is not particularly recommended, so make sure you have appropriate
| systems in place to revoke the token if necessary.
| |
*/ */
'user' => 'App\Models\Access\User\User', 'refresh_ttl' => env('JWT_REFRESH_TTL', 20160),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| User identifier | JWT hashing algorithm
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| |
| Specify a unique property of the user that will be added as the 'sub' | Specify the hashing algorithm that will be used to sign the token.
| claim of the token payload. |
| See here: https://github.com/namshi/jose/tree/master/src/Namshi/JOSE/Signer/OpenSSL
| for possible values.
| |
*/ */
'identifier' => 'id', 'algo' => env('JWT_ALGO', 'HS256'),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
...@@ -98,7 +146,32 @@ return [ ...@@ -98,7 +146,32 @@ return [
| |
*/ */
'required_claims' => ['iss', 'iat', 'exp', 'nbf', 'sub', 'jti'], 'required_claims' => [
'iss',
'iat',
'exp',
'nbf',
'sub',
'jti',
],
/*
|--------------------------------------------------------------------------
| Persistent Claims
|--------------------------------------------------------------------------
|
| Specify the claim keys to be persisted when refreshing a token.
| `sub` and `iat` will automatically be persisted, in
| addition to the these claims.
|
| Note: If a claim does not exist then it will be ignored.
|
*/
'persistent_claims' => [
// 'foo',
// 'bar',
],
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
...@@ -112,28 +185,49 @@ return [ ...@@ -112,28 +185,49 @@ return [
'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true), 'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true),
/*
| -------------------------------------------------------------------------
| Blacklist Grace Period
| -------------------------------------------------------------------------
|
| When multiple concurrent requests are made with the same JWT,
| it is possible that some of them fail, due to token regeneration
| on every request.
|
| Set grace period in seconds to prevent parallel request failure.
|
*/
'blacklist_grace_period' => env('JWT_BLACKLIST_GRACE_PERIOD', 0),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Providers | Cookies encryption
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| |
| Specify the various providers used throughout the package. | By default Laravel encrypt cookies for security reason.
| If you decide to not decrypt cookies, you will have to configure Laravel
| to not encrypt your cookie token by adding its name into the $except
| array available in the middleware "EncryptCookies" provided by Laravel.
| see https://laravel.com/docs/master/responses#cookies-and-encryption
| for details.
|
| Set it to false if you don't want to decrypt cookies.
| |
*/ */
'providers' => [ 'decrypt_cookies' => true,
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| User Provider | Providers
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| |
| Specify the provider that is used to find the user based | Specify the various providers used throughout the package.
| on the subject claim
| |
*/ */
'user' => 'Tymon\JWTAuth\Providers\User\EloquentUserAdapter', 'providers' => [
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
...@@ -144,7 +238,7 @@ return [ ...@@ -144,7 +238,7 @@ return [
| |
*/ */
'jwt' => 'Tymon\JWTAuth\Providers\JWT\NamshiAdapter', 'jwt' => Tymon\JWTAuth\Providers\JWT\Namshi::class,
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
...@@ -155,18 +249,18 @@ return [ ...@@ -155,18 +249,18 @@ return [
| |
*/ */
'auth' => 'Tymon\JWTAuth\Providers\Auth\IlluminateAuthAdapter', 'auth' => Tymon\JWTAuth\Providers\Auth\Illuminate::class,
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Storage Provider | Storage Provider
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| |
| Specify the provider that is used to store tokens in the blacklist | Specify the provider that is used to store tokens in the blacklist.
| |
*/ */
'storage' => 'Tymon\JWTAuth\Providers\Storage\IlluminateCacheAdapter', 'storage' => Tymon\JWTAuth\Providers\Storage\Illuminate::class,
], ],
......
<?php
return [
'messages' => [
'registeration' => [
'success' => 'You have registered successfully. Please check your email for activation!',
],
'login' => [
'success' => 'Login Successfull.',
'failed' => 'Invalid Credentials! Please try again.',
],
'logout' => [
'success' => 'Successfully logged out.',
],
'forgot_password' => [
'success' => 'We have sent email with reset password link. Please check your inbox!.',
'validation' => [
'email_not_found' => 'This email address is not registered.',
],
],
'refresh' => [
'token' => [
'not_provided' => 'Token not provided.',
],
'status' => 'Ok',
],
],
];
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<footer class="main-footer"> <footer class="main-footer">
<!-- To the right --> <!-- To the right -->
<div class="pull-right hidden-xs"> <div class="pull-right hidden-xs">
<a href="http://laravel-boilerplate.com" target="_blank">{{ trans('strings.backend.general.boilerplate_link') }}</a> <a href="http://laravel-admin.com" target="_blank">{{ trans('strings.backend.general.boilerplate_link') }}</a>
</div> </div>
<!-- Default to the left --> <!-- Default to the left -->
<strong>Copyright &copy; {{ date('Y') }} <a href="#">{{ app_name() }}</a>.</strong> {{ trans('strings.backend.general.all_rights_reserved') }} <strong>Copyright &copy; {{ date('Y') }} <a href="#">{{ app_name() }}</a>.</strong> {{ trans('strings.backend.general.all_rights_reserved') }}
......
...@@ -14,13 +14,21 @@ ...@@ -14,13 +14,21 @@
Route::group(['namespace' => 'Api\V1', 'prefix' => 'v1', 'as' => 'v1.'], function () { Route::group(['namespace' => 'Api\V1', 'prefix' => 'v1', 'as' => 'v1.'], function () {
Route::group(['prefix' => 'auth'], function () { Route::group(['prefix' => 'auth'], function () {
Route::post('/login', 'AuthController@authenticate'); Route::post('register', 'RegisterController@register');
Route::post('/logout', 'AuthController@logout'); Route::post('login', 'AuthController@login');
Route::post('/check', 'AuthController@check'); });
Route::post('/register', 'AuthController@register');
Route::get('/activate/{token}', 'AuthController@activate'); Route::group(['middleware' => ['jwt.auth']], function () {
Route::post('/password', 'AuthController@password'); Route::group(['prefix' => 'auth'], function () {
Route::post('/validate-password-reset', 'AuthController@validatePasswordReset'); Route::post('logout', 'AuthController@logout');
Route::post('/reset', 'AuthController@reset'); Route::post('refresh', 'AuthController@refresh');
// Password Reset Routes
Route::post('password/email', 'ForgotPasswordController@sendResetLinkEmail');
Route::post('password/reset', 'ResetPasswordController@reset')->name('password.reset');
});
// Users
Route::resource('users', 'UsersController');
}); });
}); });
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment