Commit c07bf5ee authored by Viral Solani's avatar Viral Solani

API Authentication with JWT

parent 07ff00a8
<?php
namespace App\Http\Controllers\API\V1;
use App\Http\Controllers\Controller;
use Illuminate\Http\Response as IlluminateResponse;
use Response;
/**
* Base API Controller.
*/
class APIController extends Controller
{
/**
* default status code.
*
* @var int
*/
protected $statusCode = 200;
/**
* get the status code.
*
* @return statuscode
*/
public function getStatusCode()
{
return $this->statusCode;
}
/**
* set the status code.
*
* @param [type] $statusCode [description]
*
* @return mix
*/
public function setStatusCode($statusCode)
{
$this->statusCode = $statusCode;
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.
*
* @param array $data
* @param array $headers
*
* @return mix
*/
public function respond($data, $headers = [])
{
return response()->json($data, $this->getStatusCode(), $headers);
}
/**
* respond with pagincation.
*
* @param Paginator $items
* @param array $data
*
* @return mix
*/
public function respondWithPagination($items, $data)
{
$data = array_merge($data, [
'paginator' => [
'total_count' => $items->total(),
'total_pages' => ceil($items->total() / $items->perPage()),
'current_page' => $items->currentPage(),
'limit' => $items->perPage(),
],
]);
return $this->respond($data);
}
/**
* respond with error.
*
* @param $message
*
* @return mix
*/
public function respondWithError($message)
{
return $this->respond([
'error' => [
'message' => $message,
'status_code' => $this->getStatusCode(),
],
]);
}
/**
* Respond Created.
*
* @param string $message
*
* @return mix
*/
public function respondCreated($message)
{
return $this->setStatusCode(201)->respond([
'message' => $message,
]);
}
/**
* Throw Validation.
*
* @param string $message
*
* @return mix
*/
public function throwValidation($message)
{
return $this->setStatusCode(422)
->respondWithError($message);
}
}
<?php
namespace App\Http\Controllers\Api\V1;
use JWTAuth;
use Validator;
use Illuminate\Http\Request;
use App\Models\Access\User\User;
use App\Notifications\Activated;
use App\Notifications\Activation;
use App\Notifications\PasswordReset;
use App\Notifications\PasswordResetted;
use Tymon\JWTAuth\Exceptions\JWTException;
/**
* AuthController.
*/
class AuthController extends APIController
{
/**
* Authenticate User
*
* @param Request $request
* @return {mix}
*/
public function authenticate(Request $request)
{
$credentials = $request->only('email', 'password');
try {
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) {
return $this->throwValidation('Your account hasn\'t been activated. Please check your email & activate account.');
}
return response()->json(['message' => 'You are successfully logged in!', 'token' => $token]);
}
public function check()
{
try {
JWTAuth::parseToken()->authenticate();
} catch (JWTException $e) {
return response(['authenticated' => false]);
}
return response(['authenticated' => true]);
}
public function logout()
{
try {
$token = JWTAuth::getToken();
if ($token) {
JWTAuth::invalidate($token);
}
} catch (JWTException $e) {
return response()->json($e->getMessage(), 500);
}
return response()->json(['message' => 'You are successfully logged out!']);
}
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 response()->json(['message' => $validation->messages()->first()], 422);
}
$user = User::create([
'email' => request('email'),
'status' => 'pending_activation',
'password' => bcrypt(request('password')),
]);
$user->activation_token = generateUuid();
$user->save();
/* $profile = new Profile();
$profile->first_name = request('first_name');
$profile->last_name = request('last_name');
$user->profile()->save($profile);*/
$user->notify(new Activation($user));
return response()->json(['message' => 'You have registered successfully. Please check your email for activation!']);
}
public function activate($activation_token)
{
$user = User::whereActivationToken($activation_token)->first();
if (!$user) {
return response()->json(['message' => 'Invalid activation token!'], 422);
}
if ($user->status == 'activated') {
return response()->json(['message' => 'Your account has already been activated!'], 422);
}
if ($user->status != 'pending_activation') {
return response()->json(['message' => 'Invalid activation token!'], 422);
}
$user->status = 'activated';
$user->save();
$user->notify(new Activated($user));
return response()->json(['message' => 'Your account has been activated!']);
}
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\Api\V1\Controllers;
use App\Http\Controllers\Controller;
use App\Repositories\Api\CmsPage\CmsPageRepository;
class CmsPageController extends Controller
{
public function __construct(CmsPageRepository $cmsgpage)
{
$this->cmsgpage = $cmsgpage;
}
public function showCmsPage($page_slug)
{
$result = $this->cmsgpage->findBySlug($page_slug);
return response()
->json([
'status' => 'ok',
'data' => $result,
]);
}
}
<?php
namespace App\Api\V1\Controllers;
use App\Api\V1\Requests\ForgotPasswordRequest;
use App\Http\Controllers\Controller;
use App\Mail\ForgotPasswordMail;
use App\Repositories\Api\User\PasswordResetRepository;
use App\Repositories\Api\User\UserRepository;
use Carbon\Carbon;
use Illuminate\Support\Facades\Password;
use Symfony\Component\HttpKernel\Exception\HttpException;
/**
* Class ForgotPasswordController.
*/
class ForgotPasswordController extends Controller
{
/**
* @var UserRepository
*/
protected $user;
/**
* ForgotPasswordController constructor.
*
* @param UserRepository $user
*/
public function __construct(UserRepository $user, PasswordResetRepository $passwordreset)
{
$this->user = $user;
$this->passwordreset = $passwordreset;
}
/**
* Recovery password api.
*/
public function forgotpassword(ForgotPasswordRequest $request)
{
$check_user = $this->user->checkUser($request->get('email'));
if (!(empty($check_user))) {
$otp = $this->user->generateOTP();
$attributes = [
'email' => $request->get('email'),
'token' => $otp,
'created_at' => Carbon::now(),
];
$check_reset = $this->passwordreset->getByEmail($request->get('email'));
if (empty($check_reset)) {
$token = $this->passwordreset->create($attributes);
} else {
$token = $this->passwordreset->update($attributes);
}
$forgot_mail = \Mail::to($request->get('email'))->send(new ForgotPasswordMail($otp));
return response()->json([
'status' => 'ok',
'data' => ['token' => $otp],
], 200);
}
throw new HttpException(500, trans('validation.api.forgotpassword.email_not_valid'));
}
}
<?php
namespace App\Api\V1\Controllers;
use App\Api\V1\Requests\LoginRequest;
use App\http\Controllers\Controller;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\JWTAuth;
/**
* Class LoginController.
*/
class LoginController extends Controller
{
/*
* Login api for user
*/
public function login(LoginRequest $request, JWTAuth $JWTAuth)
{
$credentials = [
'email' => $request->email,
'password' => $request->password,
];
try {
/**
* check credentials valid or not.
*/
$token = $JWTAuth->attempt($credentials);
if (!$token) {
throw new AccessDeniedHttpException(trans('validation.api.login.username_password_didnt_match'));
}
} catch (JWTException $e) {
throw new HttpException(500);
}
return response()
->json([
'status' => 'ok',
'token' => $token,
]);
}
}
<?php
namespace App\Api\V1\Controllers;
use App\Api\V1\Requests\ConfirmAccountRequest;
use App\Api\V1\Requests\RegisterRequest;
use App\Http\Controllers\Controller;
use App\Repositories\Api\User\UserRepository;
use Symfony\Component\HttpKernel\Exception\HttpException;
/**
* Class RegisterController.
*/
class RegisterController extends Controller
{
/**
* @var UserRepository
*/
protected $user;
/**
* RegisterController constructor.
*
* @param UserRepository $user
*/
public function __construct(UserRepository $user)
{
$this->user = $user;
}
/*
* Register api.
*/
public function Register(RegisterRequest $request)
{
$user = $this->user->create($request->all());
return response()
->json([
'status' => 'ok',
]);
}
/*
* Confirm account api
*/
public function confirmAccount(ConfirmAccountRequest $request)
{
$user = $this->user->checkUser($request->get('email'));
if (!(empty($user))) {
if ($user[0]['confirmation_code'] != '') {
if (md5($request->get('otp')) == $user[0]['confirmation_code']) {
$checkconfirmation = $this->user->checkconfirmation($request->get('email'));
if ($checkconfirmation[0]['confirmed'] == 0) {
$confirmuser = $this->user->confirmUser($request->get('email'));
} else {
throw new HttpException(500, trans('validation.api.confirmaccount.already_confirmed'));
}
} else {
throw new HttpException(500, trans('validation.api.confirmaccount.invalid_otp'));
}
}
} else {
throw new HttpException(500, trans('validation.api.confirmaccount.invalid_email'));
}
return response()
->json([
'status' => 'ok',
]);
}
}
<?php
namespace App\Api\V1\Controllers;
use App\Api\V1\Requests\ResetPasswordRequest;
use App\Http\Controllers\Controller;
use App\Repositories\Api\User\PasswordResetRepository;
use App\Repositories\Api\User\UserRepository;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Password;
use Symfony\Component\HttpKernel\Exception\HttpException;
/**
* Class ResetPasswordController.
*/
class ResetPasswordController extends Controller
{
/**
* @var UserRepository
*/
protected $user;
/**
* ResetPasswordController constructor.
*
* @param UserRepository $user
*/
public function __construct(UserRepository $user, PasswordResetRepository $passwordreset)
{
$this->user = $user;
$this->passwordreset = $passwordreset;
}
/**
* Resetpassword api.
*/
public function resetpassword(ResetPasswordRequest $request)
{
$check_user = $this->user->checkUser($request->get('email'));
if (!(empty($check_user))) {
$response = $this->passwordreset->checkUser($this->credentials($request));
if (!(empty($response))) {
$resetpassword = $this->user->resetpassword($this->credentials($request));
$remove_token = $this->passwordreset->delete($this->credentials($request));
return response()
->json([
'status' => 'ok',
]);
}
throw new HttpException(500, trans('validation.api.resetpassword.token_not_valid'));
}
throw new HttpException(500, trans('validation.api.resetpassword.email_not_valid'));
}
/**
* Get the password reset credentials from the request.
*
* @param ResetPasswordRequest $request
*
* @return array
*/
protected function credentials(ResetPasswordRequest $request)
{
return $request->all(
'email', 'password', 'password_confirmation', 'token'
);
}
}
<?php
namespace App\Api\V1\Controllers;
use App\http\Controllers\Controller;
use App\Repositories\Api\User\UserRepository;
use Dingo\Api\Routing\Helpers;
use Illuminate\Http\Request;
use JWTAuth;
/**
* Class UserDetailController.
*/
class UserDetailController extends Controller
{
use Helpers;
/**
* @var UserRepository
*/
protected $user;
/**
* ResetPasswordController constructor.
*
* @param UserRepository $user
*/
public function __construct(UserRepository $user)
{
$this->user = $user;
}
/*
* User details api
*/
public function userDetails(Request $request)
{
$currentUser = JWTAuth::parseToken()->authenticate();
$user = $this->user->getById($currentUser->id);
return response()
->json([
'status' => 'ok',
'data' => $user,
]);
}
}
......@@ -73,6 +73,8 @@ class Kernel extends HttpKernel
*/
'access.routeNeedsRole' => \App\Http\Middleware\RouteNeedsRole::class,
'access.routeNeedsPermission' => \App\Http\Middleware\RouteNeedsPermission::class,
'jwt.auth' => \App\Http\Middleware\VerifyJWTToken::class,
#'jwt.auth' => \App\Http\Middleware\VerifyJWTToken::class,
'jwt.auth' => \Tymon\JWTAuth\Middleware\GetUserFromToken::class,
'jwt.refresh' => \Tymon\JWTAuth\Middleware\RefreshToken::class,
];
}
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class Activated extends Notification
{
use Queueable;
/**
* Create a new notification instance.
*
* @return void
*/
protected $user;
public function __construct($user)
{
$this->user = $user;
}
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
*
* @return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
*
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
$url = url('/');
return (new MailMessage())
->greeting('Hello!')
->line('Your account has been activated.')
->line('Click on the below link to go to our application!')
->action('Proceed', $url)
->line('Thank you for using our application!');
}
/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
*
* @return array
*/
public function toArray($notifiable)
{
return [
//
];
}
}
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class Activation extends Notification
{
use Queueable;
/**
* Create a new notification instance.
*
* @return void
*/
protected $user;
public function __construct($user)
{
$this->user = $user;
}
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
*
* @return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
*
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
$url = url('/auth/'.$this->user->activation_token.'/activate');
return (new MailMessage())
->greeting('Hello!')
->line('Thank you for registering an account with us.')
->line('Click on the below link to verify your email!')
->action('Verify now!', $url)
->line('Thank you for using our application!');
}
/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
*
* @return array
*/
public function toArray($notifiable)
{
return [
//
];
}
}
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class PasswordReset extends Notification
{
use Queueable;
/**
* Create a new notification instance.
*
* @return void
*/
protected $user;
protected $token;
public function __construct($user, $token)
{
$this->user = $user;
$this->token = $token;
}
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
*
* @return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
*
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
$url = url('/password/reset/'.$this->token);
return (new MailMessage())
->greeting('Hello!')
->line('We have recevied password reset request from you!')
->line('Click on the below link to reset your password.')
->action('Reset Password', $url)
->line('If you haven\'t requested for password reset, please ignore this email.')
->line('Thank you!');
}
/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
*
* @return array
*/
public function toArray($notifiable)
{
return [
//
];
}
}
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class PasswordResetted extends Notification
{
use Queueable;
/**
* Create a new notification instance.
*
* @return void
*/
protected $user;
public function __construct($user)
{
$this->user = $user;
}
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
*
* @return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
*
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
$url = url('/');
return (new MailMessage())
->greeting('Hello!')
->line('Your password has been reset successfully!')
->line('Click on the below link to continue login.')
->action('Login', $url)
->line('If you haven\'t changed your password, please contact administrator.')
->line('Thank you!');
}
/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
*
* @return array
*/
public function toArray($notifiable)
{
return [
//
];
}
}
This diff is collapsed.
......@@ -69,7 +69,7 @@ return [
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\Access\User\User::class,
'model' => User::class,
],
// 'users' => [
......
{
"/js/frontend.js": "/js/frontend.70ee44a92d84e7318a9d.js",
"/js/backend.js": "/js/backend.9cdae6ab449e701ce881.js",
"/js/frontend.js": "/js/frontend.2bea3bf4ad584622eb6b.js",
"/js/backend.js": "/js/backend.321ce1e5ca635759765f.js",
"/mix.js": "/mix.247ab120fe7680658924.js",
"/css/frontend.css": "/css/frontend.3af0a6cbd7d1d8d042f2a37e97008b7c.css",
"/css/backend.css": "/css/backend.f8550f50504e5b8ef6055285205f223a.css",
......
<?php
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::group(['namespace' => 'Api\V1', 'prefix' => 'v1', 'as' => 'v1.'], function () {
Route::group(['prefix' => 'auth'], function () {
Route::post('/login', 'AuthController@authenticate');
Route::post('/logout', 'AuthController@logout');
Route::post('/check', 'AuthController@check');
Route::post('/register', 'AuthController@register');
Route::get('/activate/{token}', 'AuthController@activate');
Route::post('/password', 'AuthController@password');
Route::post('/validate-password-reset', 'AuthController@validatePasswordReset');
Route::post('/reset', 'AuthController@reset');
});
});
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