mirror of
https://github.com/grocy/grocy.git
synced 2025-04-29 09:39:57 +00:00
Use session/cookie based authentication with login form instead of basic auth
This commit is contained in:
parent
bd3155d39b
commit
23146417e6
44
Grocy.php
44
Grocy.php
@ -101,4 +101,48 @@ class Grocy
|
||||
|
||||
return self::$InstalledVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public static function IsValidSession($sessionKey)
|
||||
{
|
||||
if ($sessionKey === null || empty($sessionKey))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return file_exists(__DIR__ . "/data/sessions/$sessionKey.txt");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function CreateSession()
|
||||
{
|
||||
if (!file_exists(__DIR__ . '/data/sessions'))
|
||||
{
|
||||
mkdir(__DIR__ . '/data/sessions');
|
||||
}
|
||||
|
||||
$now = time();
|
||||
foreach (new FilesystemIterator(__DIR__ . '/data/sessions') as $file)
|
||||
{
|
||||
if ($now - $file->getCTime() >= 2678400) //31 days
|
||||
{
|
||||
unlink(__DIR__ . '/data/sessions/' . $file->getFilename());
|
||||
}
|
||||
}
|
||||
|
||||
$newSessionKey = uniqid() . uniqid() . uniqid();
|
||||
file_put_contents(__DIR__ . "/data/sessions/$newSessionKey.txt", '');
|
||||
return $newSessionKey;
|
||||
}
|
||||
|
||||
public static function RemoveSession($sessionKey)
|
||||
{
|
||||
unlink(__DIR__ . "/data/sessions/$sessionKey.txt");
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
"require": {
|
||||
"slim/slim": "^3.8",
|
||||
"slim/php-view": "^2.2",
|
||||
"morris/lessql": "^0.3.4",
|
||||
"tuupola/slim-basic-auth": "^2.2"
|
||||
"morris/lessql": "^0.3.4"
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,7 @@
|
||||
<Compile Include="GrocyDbMigrator.php" />
|
||||
<Compile Include="index.php" />
|
||||
<Compile Include="views\consume.php" />
|
||||
<Compile Include="views\login.php" />
|
||||
<Compile Include="views\inventory.php" />
|
||||
<Compile Include="views\shoppinglistform.php" />
|
||||
<Compile Include="views\shoppinglist.php" />
|
||||
@ -60,6 +61,7 @@
|
||||
<Content Include="views\consume.js" />
|
||||
<Content Include="views\dashboard.js" />
|
||||
<Content Include="views\inventory.js" />
|
||||
<Content Include="views\login.js" />
|
||||
<Content Include="views\shoppinglistform.js" />
|
||||
<Content Include="views\shoppinglist.js" />
|
||||
<Content Include="views\purchase.js" />
|
||||
|
64
index.php
64
index.php
@ -15,6 +15,7 @@ require_once __DIR__ . '/GrocyPhpHelper.php';
|
||||
$app = new \Slim\App(new \Slim\Container([
|
||||
'settings' => [
|
||||
'displayErrorDetails' => true,
|
||||
'determineRouteBeforeAppMiddleware' => true
|
||||
],
|
||||
]));
|
||||
$container = $app->getContainer();
|
||||
@ -22,18 +23,65 @@ $container['renderer'] = new PhpRenderer('./views');
|
||||
|
||||
if (!Grocy::IsDemoInstallation())
|
||||
{
|
||||
$isHttpsReverseProxied = !empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https';
|
||||
$app->add(new \Slim\Middleware\HttpBasicAuthentication([
|
||||
'realm' => 'grocy',
|
||||
'secure' => !$isHttpsReverseProxied,
|
||||
'users' => [
|
||||
HTTP_USER => HTTP_PASSWORD
|
||||
]
|
||||
]));
|
||||
$sessionMiddleware = function(Request $request, Response $response, callable $next)
|
||||
{
|
||||
$route = $request->getAttribute('route');
|
||||
$routeName = $route->getName();
|
||||
|
||||
if (!Grocy::IsValidSession($_COOKIE['grocy_session']) && $routeName !== 'login')
|
||||
{
|
||||
$response = $response->withRedirect('/login');
|
||||
}
|
||||
else
|
||||
{
|
||||
$response = $next($request, $response);
|
||||
}
|
||||
|
||||
return $response;
|
||||
};
|
||||
|
||||
$app->add($sessionMiddleware);
|
||||
}
|
||||
|
||||
$db = Grocy::GetDbConnection();
|
||||
|
||||
$app->get('/login', function(Request $request, Response $response)
|
||||
{
|
||||
return $this->renderer->render($response, '/layout.php', [
|
||||
'title' => 'Login',
|
||||
'contentPage' => 'login.php'
|
||||
]);
|
||||
})->setName('login');
|
||||
|
||||
$app->post('/login', function(Request $request, Response $response)
|
||||
{
|
||||
$postParams = $request->getParsedBody();
|
||||
if (isset($postParams['username']) && isset($postParams['password']))
|
||||
{
|
||||
if ($postParams['username'] === HTTP_USER && $postParams['password'] === HTTP_PASSWORD)
|
||||
{
|
||||
$sessionKey = Grocy::CreateSession();
|
||||
setcookie('grocy_session', $sessionKey, time()+2592000); //30 days
|
||||
|
||||
return $response->withRedirect('/');
|
||||
}
|
||||
else
|
||||
{
|
||||
return $response->withRedirect('/login?invalid=true');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return $response->withRedirect('/login?invalid=true');
|
||||
}
|
||||
})->setName('login');
|
||||
|
||||
$app->get('/logout', function(Request $request, Response $response)
|
||||
{
|
||||
Grocy::RemoveSession($_COOKIE['grocy_session']);
|
||||
return $response->withRedirect('/');
|
||||
});
|
||||
|
||||
$app->get('/', function(Request $request, Response $response) use($db)
|
||||
{
|
||||
$db = Grocy::GetDbConnection(true); //For database schema migration
|
||||
|
@ -1 +1 @@
|
||||
1.3.0
|
||||
1.4.0
|
@ -38,6 +38,14 @@
|
||||
<a class="navbar-brand" href="/">grocy</a>
|
||||
</div>
|
||||
|
||||
<div id="navbar" class="navbar-collapse collapse">
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li>
|
||||
<a class="discrete-link logout-button" href="/logout"><i class="fa fa-sign-out fa-fw"></i> Logout</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="navbar-mobile" class="navbar-collapse collapse">
|
||||
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
@ -71,6 +79,12 @@
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li>
|
||||
<a class="discrete-link logout-button" href="/logout"><i class="fa fa-sign-out fa-fw"></i> Logout</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
12
views/login.js
Normal file
12
views/login.js
Normal file
@ -0,0 +1,12 @@
|
||||
$(function()
|
||||
{
|
||||
$('.logout-button').hide();
|
||||
|
||||
$('#username').focus();
|
||||
|
||||
if (Grocy.GetUriParam('invalid') === 'true')
|
||||
{
|
||||
$('#login-error').text('Invalid credentials, please try again.');
|
||||
$('#login-error').show();
|
||||
}
|
||||
});
|
23
views/login.php
Normal file
23
views/login.php
Normal file
@ -0,0 +1,23 @@
|
||||
<div class="col-md-4 col-md-offset-5 main">
|
||||
|
||||
<h1 class="page-header text-center">Login</h1>
|
||||
|
||||
<form method="post" action="/login" id="login-form">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="name">Username</label>
|
||||
<input type="text" class="form-control" required id="username" name="username" />
|
||||
<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="name">Password</label>
|
||||
<input type="password" class="form-control" required id="password" name="password" />
|
||||
<div id="login-error" class="help-block with-errors"></div>
|
||||
</div>
|
||||
|
||||
<button id="login-button" type="submit" class="btn btn-default">Login</button>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
Loading…
x
Reference in New Issue
Block a user