Created the JWT authentication for the editor so that it's more secure and can potentially be used to create a desktop app in the future. Used Tuupola's JWT auth middleware implementation to help with the auth part. Used Firebase's JWT method to create the token
Signed-off-by: rodude123 <rodude123@gmail.com>
This commit is contained in:
+19
-23
@@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php /** @noinspection PhpIncludeInspection */
|
||||
|
||||
session_start();
|
||||
////////////////// Index file //////////////
|
||||
@@ -7,40 +7,30 @@ session_start();
|
||||
////////////////////////////////////////////
|
||||
//require “routes.php”;
|
||||
require "../vendor/autoload.php";
|
||||
include "middleware.php";
|
||||
include "timelineData.php";
|
||||
include "projectData.php";
|
||||
include "user.php";
|
||||
|
||||
use api\middleware;
|
||||
use api\projectData;
|
||||
use api\timelineData;
|
||||
use api\user;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Selective\SameSiteCookie\SameSiteCookieConfiguration;
|
||||
use Slim\Factory\AppFactory;
|
||||
use Selective\SameSiteCookie\SameSiteCookieMiddleware;
|
||||
use Slim\Handlers\Strategies\RequestHandler;
|
||||
use Slim\Factory\AppFactory;
|
||||
use Tuupola\Middleware\JwtAuthentication;
|
||||
|
||||
// Start slim
|
||||
$app = AppFactory::create();
|
||||
// create middleware
|
||||
$app->addRoutingMiddleware();
|
||||
|
||||
$ssConfig = new SameSiteCookieConfiguration(["same_site" => "strict"]);
|
||||
|
||||
// add in same site cookie stuff
|
||||
$app->add(new SameSiteCookieMiddleware($ssConfig));
|
||||
|
||||
// for error checking
|
||||
$errorMiddleware = $app->addErrorMiddleware(true, true, true);
|
||||
|
||||
// set base path for all routes
|
||||
$app->setBasePath("/api");
|
||||
|
||||
// return all responses as JSON
|
||||
/*$app->add(function($request, $handler) {
|
||||
$response = $handler->handle($request);
|
||||
return $response->withHeader("Content-Type", "application/json");
|
||||
});*/
|
||||
// Add middleware
|
||||
new middleware($app);
|
||||
|
||||
$timelineData = new timelineData();
|
||||
$projectData = new projectData();
|
||||
@@ -277,8 +267,9 @@ $app->post("/user/login", function (Request $request, Response $response)
|
||||
if ($user->checkUser($data["username"], $data["password"]))
|
||||
{
|
||||
// yay, user is logged in
|
||||
$_SESSION["token"] = $user->createToken();
|
||||
$_SESSION["token"] = $user->createToken($data["username"]);
|
||||
$_SESSION["username"] = $data["username"];
|
||||
$response->getBody()->write(json_encode(array("token" => $_SESSION["token"])));
|
||||
return $response;
|
||||
}
|
||||
return $response->withStatus(401);
|
||||
@@ -297,7 +288,7 @@ $app->get("/user/isLoggedIn", function (Request $request, Response $response)
|
||||
if (empty($_SESSION["token"]))
|
||||
{
|
||||
// user is logged in but no token was created
|
||||
$_SESSION["token"] = $user->createToken();
|
||||
$_SESSION["token"] = $user->createToken($_SESSION["username"]);
|
||||
return $response;
|
||||
}
|
||||
|
||||
@@ -319,8 +310,7 @@ $app->get("/user/checkResetEmail/{email}", function (Request $request, Response
|
||||
if ($user->checkEmail($args["email"]))
|
||||
{
|
||||
// yay email does exist
|
||||
$token = $user->sendResetEmail($args["email"]);
|
||||
$_SESSION["resetToken"] = $token;
|
||||
$_SESSION["resetToken"] = $user->sendResetEmail($args["email"]);
|
||||
$_SESSION["resetEmail"] = $args["email"];
|
||||
return $response;
|
||||
}
|
||||
@@ -335,7 +325,7 @@ $app->get("/user/resendEmail", function (Request $request, Response $response)
|
||||
return $response->withStatus(401);
|
||||
}
|
||||
global $user;
|
||||
$user->sendResetEmail($_SESSION["resetEmail"]);
|
||||
$_SESSION["resetToken"] = $user->sendResetEmail($_SESSION["resetEmail"]);
|
||||
return $response;
|
||||
});
|
||||
|
||||
@@ -383,4 +373,10 @@ $app->post("/user/changePassword", function (Request $request, Response $respons
|
||||
return $response->withStatus(500);
|
||||
});
|
||||
|
||||
$app->post("/projectData", function (Request $request, Response $response)
|
||||
{
|
||||
$response->getBody()->write(json_encode(array("test" => "test")));
|
||||
return $response;
|
||||
});
|
||||
|
||||
$app->run();
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
// middleware
|
||||
namespace api;
|
||||
|
||||
use Slim\App;
|
||||
use Selective\SameSiteCookie\SameSiteCookieConfiguration;
|
||||
use Selective\SameSiteCookie\SameSiteCookieMiddleware;
|
||||
use Tuupola\Middleware\JwtAuthentication;
|
||||
use Tuupola\Middleware\JwtAuthentication\RequestMethodRule;
|
||||
use Tuupola\Middleware\JwtAuthentication\RequestPathRule;
|
||||
|
||||
/**
|
||||
* Middleware
|
||||
* Define all middleware functions
|
||||
*/
|
||||
class middleware
|
||||
{
|
||||
/**
|
||||
* Constructor for middleware
|
||||
* @param App $app - Slim App
|
||||
*/
|
||||
function __construct(App $app)
|
||||
{
|
||||
$this->baseMiddleware($app);
|
||||
$this->sameSiteConfig($app);
|
||||
$this->jwtAuth($app);
|
||||
$this->returnAsJSON($app);
|
||||
}
|
||||
|
||||
/**
|
||||
* Base middleware
|
||||
* @param App $app - Slim App
|
||||
*/
|
||||
function baseMiddleware(App $app): void
|
||||
{
|
||||
$app->addRoutingMiddleware();
|
||||
}
|
||||
|
||||
/**
|
||||
* SameSite Cookie Configuration
|
||||
* @param App $app - Slim App
|
||||
*/
|
||||
function sameSiteConfig(App $app): void
|
||||
{
|
||||
$ssConfig = new SameSiteCookieConfiguration(["same_site" => "strict"]);
|
||||
$app->add(new SameSiteCookieMiddleware($ssConfig));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all responses as JSON
|
||||
* @param App $app - Slim App
|
||||
*/
|
||||
function returnAsJSON(App $app): void
|
||||
{
|
||||
$app->add(function ($request, $handler)
|
||||
{
|
||||
$response = $handler->handle($request);
|
||||
return $response->withHeader("Content-Type", "application/json");
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* JWT Authentication
|
||||
* @param App $app - Slim App
|
||||
*/
|
||||
function jwtAuth(App $app): void
|
||||
{
|
||||
$jwtSecret = getSecretKey();
|
||||
$app->add(new JwtAuthentication([
|
||||
"rules" => [
|
||||
new RequestPathRule([
|
||||
"path" => ["/api/projectData", "/api/timeline/[a-z]*", "/api/user/testMethod"],
|
||||
"ignore" => ["/api/contact", "/api/user/login", "/api/user/changePassword"]
|
||||
]),
|
||||
new RequestMethodRule([
|
||||
"ignore" => ["OPTIONS", "GET"]
|
||||
])
|
||||
],
|
||||
"secret" => $jwtSecret,
|
||||
"error" => function ($response)
|
||||
{
|
||||
session_destroy();
|
||||
$response->getBody()->write(json_encode(array("status" => "401", "message" =>
|
||||
"Unauthorized, please provide a valid token")));
|
||||
return $response->withStatus(401);
|
||||
}
|
||||
]));
|
||||
$app->addErrorMiddleware(true, true, true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,6 +10,10 @@ require_once "./config.php";
|
||||
*/
|
||||
class projectData
|
||||
{
|
||||
/**
|
||||
* Get all project data
|
||||
* @return array - Array of all project data or error message
|
||||
*/
|
||||
function getProjectData(): array
|
||||
{
|
||||
$conn = dbConn();
|
||||
|
||||
@@ -10,6 +10,10 @@ require_once "./config.php";
|
||||
*/
|
||||
class timelineData
|
||||
{
|
||||
/**
|
||||
* Get all education data
|
||||
* @return array - Array of all education data or error message
|
||||
*/
|
||||
function getEduData(): array
|
||||
{
|
||||
$conn = dbConn();
|
||||
@@ -26,6 +30,10 @@ class timelineData
|
||||
return array("errorMessage" => "Error, edu data not found");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all work data
|
||||
* @return array - Array of all work data or error message
|
||||
*/
|
||||
function getWorkData(): array
|
||||
{
|
||||
$conn = dbConn();
|
||||
|
||||
+46
-7
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
namespace api;
|
||||
use Firebase\JWT\JWT;
|
||||
use PDO;
|
||||
|
||||
require_once "./config.php";
|
||||
@@ -10,7 +11,13 @@ require_once "./config.php";
|
||||
*/
|
||||
class user
|
||||
{
|
||||
function checkUser($username, $password): bool
|
||||
/**
|
||||
* Check if user exists and can be logged in
|
||||
* @param $username string - Username
|
||||
* @param $password string - Password
|
||||
* @return bool - True if logged in, false if not
|
||||
*/
|
||||
function checkUser(string $username, string $password): bool
|
||||
{
|
||||
$conn = dbConn();
|
||||
$stmt = $conn->prepare("SELECT * FROM users WHERE username = :username");
|
||||
@@ -31,12 +38,31 @@ class user
|
||||
return false;
|
||||
}
|
||||
|
||||
function createToken(): string
|
||||
/**
|
||||
* Create a JWT token
|
||||
* @param $username string - Username
|
||||
* @return string - JWT token
|
||||
*/
|
||||
function createToken(string $username): string
|
||||
{
|
||||
return uniqid("rpe-");
|
||||
$now = time();
|
||||
$future = strtotime('+6 hour',$now);
|
||||
$secretKey = getSecretKey();
|
||||
$payload = [
|
||||
"jti"=>$username,
|
||||
"iat"=>$now,
|
||||
"exp"=>$future
|
||||
];
|
||||
|
||||
return JWT::encode($payload,$secretKey,"HS256");
|
||||
}
|
||||
|
||||
function checkEmail($email): bool
|
||||
/**
|
||||
* Check if email is already in use
|
||||
* @param string $email - Email to check
|
||||
* @return bool - True if email exists, false if not
|
||||
*/
|
||||
function checkEmail(string $email): bool
|
||||
{
|
||||
$conn = dbConn();
|
||||
$stmt = $conn->prepare("SELECT * FROM users WHERE email = :email");
|
||||
@@ -52,11 +78,16 @@ class user
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send a verification email to the user
|
||||
* @param $email - email address of the user
|
||||
* @return string - verification code
|
||||
*/
|
||||
function sendResetEmail($email): string
|
||||
{
|
||||
//generate a random token and email the address
|
||||
$token = $this->createToken();
|
||||
$token = uniqid("rpe-");
|
||||
$headers1 = "From: noreply@rohitpai.co.uk\r\n";
|
||||
$headers1 .= "MIME-Version: 1.0\r\n";
|
||||
$headers1 .= "Content-Type: text/html; charset=UTF-8\r\n";
|
||||
@@ -82,7 +113,13 @@ class user
|
||||
return $token;
|
||||
}
|
||||
|
||||
function changePassword($email, $password): bool
|
||||
/**
|
||||
* Change password for an email with new password
|
||||
* @param $email string Email
|
||||
* @param $password string Password
|
||||
* @return bool - true if the password was changed, false if not
|
||||
*/
|
||||
function changePassword(string $email, string $password): bool
|
||||
{
|
||||
$conn = dbConn();
|
||||
$stmt = $conn->prepare("UPDATE users SET password = :password WHERE email = :email");
|
||||
@@ -96,4 +133,6 @@ class user
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user