1
0
mirror of https://github.com/delight-im/PHP-Auth.git synced 2025-08-08 09:06:29 +02:00

11 Commits

Author SHA1 Message Date
Marco
ab55f7e562 Explain how to manage session data conveniently 2016-07-20 00:37:48 +02:00
Marco
e768243798 Update dependencies 2016-07-20 00:36:18 +02:00
Marco
27a3990472 Only throttle login attempts that have wrong credentials 2016-07-09 00:58:04 +02:00
Marco
1979799480 Improve cookie handling to fix domain issues and add same-site flag 2016-07-09 00:48:55 +02:00
Marco
fff4a59be5 Include 'delight-im/cookie' as dependency for cookie handling 2016-07-09 00:14:51 +02:00
Marco
122e2b8006 Add missing '+' 2016-06-07 19:04:31 +02:00
Marco
bebd3efce2 Use Composer autoloader for tests as well 2016-06-07 19:01:56 +02:00
Marco
00dc8c3158 Enable both error reporting and assertions in 'tests' 2016-06-07 18:48:50 +02:00
Marco
e074474955 Fix list of dependencies 2016-06-07 18:42:29 +02:00
Marco
44907f3489 Add 'NOTICE' 2016-04-02 22:25:14 +02:00
Marco
ea27e8b7d3 Remove trailing newline in 'LICENSE' 2016-04-02 22:24:51 +02:00
8 changed files with 165 additions and 53 deletions

5
.gitignore vendored
View File

@@ -1 +1,6 @@
# IntelliJ
.idea/
# Composer
vendor/
composer.phar

View File

@@ -199,4 +199,3 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

5
NOTICE Normal file
View File

@@ -0,0 +1,5 @@
PHP-Auth
Copyright (c) delight.im <info@delight.im>
This product includes software developed by
delight.im (http://www.delight.im/).

View File

@@ -17,8 +17,8 @@ Completely framework-agnostic and database-agnostic.
## Requirements
* PHP 5.5.0+
* PDO
* OpenSSL
* OpenSSL extension
* MySQL 5.5.3+ **or** MariaDB 5.5.23+
## Installation
@@ -222,6 +222,10 @@ If the user is not currently signed in, this returns `null`.
$ip = $auth->getIpAddress();
```
### Read and write session data
For detailed information on how to read and write session data conveniently, please refer to [the documentation of the session library](https://github.com/delight-im/PHP-Cookie), which is included by default.
### Utilities
#### Create a random string
@@ -254,8 +258,13 @@ $uuid = \Delight\Auth\Auth::createUuid();
* logout
* full and reliable destruction of session
* session management
* protection against session hijacking
* protection against session hijacking via cross-site scripting (XSS)
* do *not* permit script-based access to cookies
* restrict cookies to HTTPS to prevent session hijacking via non-secure HTTP
* protection against session fixation attacks
* protection against cross-site request forgery (CSRF)
* works automatically (i.e. no need for CSRF tokens everywhere)
* do *not* use HTTP `GET` requests for "dangerous" operations
* throttling
* per IP address
* per account

View File

@@ -2,7 +2,9 @@
"name": "delight-im/auth",
"description": "Authentication for PHP. Simple, lightweight and secure.",
"require": {
"php": ">=5.5.0"
"php": ">=5.5.0",
"ext-openssl": "*",
"delight-im/cookie": "^1.3"
},
"type": "library",
"keywords": [ "auth", "authentication", "login", "security" ],

99
composer.lock generated Normal file
View File

@@ -0,0 +1,99 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "32e4912115e164a1a86227d49db9ac29",
"content-hash": "1a5c0056d726ae6195da0faa38f37fdd",
"packages": [
{
"name": "delight-im/cookie",
"version": "v1.3.0",
"source": {
"type": "git",
"url": "https://github.com/delight-im/PHP-Cookie.git",
"reference": "481c569d6f4bcb0391f56203f078d425b3339001"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/delight-im/PHP-Cookie/zipball/481c569d6f4bcb0391f56203f078d425b3339001",
"reference": "481c569d6f4bcb0391f56203f078d425b3339001",
"shasum": ""
},
"require": {
"delight-im/http": "^1.1",
"php": ">=5.3.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Delight\\Cookie\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"description": "Modern cookie management for PHP",
"homepage": "https://github.com/delight-im/PHP-Cookie",
"keywords": [
"cookie",
"cookies",
"csrf",
"http",
"same-site",
"samesite",
"xss"
],
"time": "2016-07-19 22:20:24"
},
{
"name": "delight-im/http",
"version": "v1.1.0",
"source": {
"type": "git",
"url": "https://github.com/delight-im/PHP-HTTP.git",
"reference": "2ca9001f047c8b4e1b7ca7281823a1a9437850f8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/delight-im/PHP-HTTP/zipball/2ca9001f047c8b4e1b7ca7281823a1a9437850f8",
"reference": "2ca9001f047c8b4e1b7ca7281823a1a9437850f8",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Delight\\Http\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"description": "Hypertext Transfer Protocol (HTTP) utilities for PHP",
"homepage": "https://github.com/delight-im/PHP-HTTP",
"keywords": [
"headers",
"http",
"https"
],
"time": "2016-07-08 21:19:02"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": ">=5.5.0",
"ext-openssl": "*"
},
"platform-dev": []
}

View File

@@ -85,7 +85,7 @@ class Auth {
session_set_cookie_params($params['lifetime'], $params['path'], $params['domain'], $params['secure'], $params['httponly']);
// start the session
@session_start();
@\Delight\Cookie\Session::start();
}
/** Improves the application's security over HTTP(S) by setting specific headers */
@@ -266,9 +266,6 @@ class Auth {
* @throws AuthError if an internal problem occurred (do *not* catch)
*/
public function login($email, $password, $remember = false) {
$this->throttle(self::THROTTLE_ACTION_LOGIN);
$this->throttle(self::THROTTLE_ACTION_LOGIN, $email);
$email = isset($email) ? trim($email) : null;
if (empty($email)) {
throw new InvalidEmailException();
@@ -308,10 +305,16 @@ class Auth {
}
}
else {
$this->throttle(self::THROTTLE_ACTION_LOGIN);
$this->throttle(self::THROTTLE_ACTION_LOGIN, $email);
throw new InvalidPasswordException();
}
}
else {
$this->throttle(self::THROTTLE_ACTION_LOGIN);
$this->throttle(self::THROTTLE_ACTION_LOGIN, $email);
throw new InvalidEmailException();
}
}
@@ -388,7 +391,18 @@ class Auth {
}
// set the cookie with the selector and token
$result = setcookie(self::COOKIE_NAME_REMEMBER, $content, $expires, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
$cookie = new \Delight\Cookie\Cookie(self::COOKIE_NAME_REMEMBER);
$cookie->setValue($content);
$cookie->setExpiryTime($expires);
if (!empty($params['path'])) {
$cookie->setPath($params['path']);
}
if (!empty($params['domain'])) {
$cookie->setDomain($params['domain']);
}
$cookie->setHttpOnly($params['httponly']);
$cookie->setSecureOnly($params['secure']);
$result = $cookie->save();
if ($result === false) {
throw new HeadersAlreadySentError();
@@ -410,7 +424,7 @@ class Auth {
$stmt->execute();
// re-generate the session ID to prevent session fixation attacks
session_regenerate_id(true);
\Delight\Cookie\Session::regenerate(true);
// save the user data in the session
$this->setLoggedIn(true);
@@ -456,8 +470,17 @@ class Auth {
// get our cookie settings
$params = $this->createCookieSettings();
// set the cookie with the selector and token
$result = setcookie(session_name(), '', time() - 3600, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
// cause the session cookie to be deleted
$cookie = new \Delight\Cookie\Cookie(session_name());
if (!empty($params['path'])) {
$cookie->setPath($params['path']);
}
if (!empty($params['domain'])) {
$cookie->setDomain($params['domain']);
}
$cookie->setHttpOnly($params['httponly']);
$cookie->setSecureOnly($params['secure']);
$result = $cookie->delete();
if ($result === false) {
throw new HeadersAlreadySentError();
@@ -829,8 +852,6 @@ class Auth {
// get the default cookie settings
$params = session_get_cookie_params();
// optimize the cookie domain
$params['domain'] = self::optimizeCookieDomain($params['domain']);
// check if we want to send cookies via SSL/TLS only
$params['secure'] = $params['secure'] || $this->useHttps;
// check if we want to send cookies via HTTP(S) only
@@ -840,41 +861,6 @@ class Auth {
return $params;
}
/**
* Optimizes the specified cookie domain
*
* @param string $domain the supplied cookie domain
* @return string the optimized cookie domain
*/
private static function optimizeCookieDomain($domain) {
// if no domain has been explicitly provided
if (empty($domain)) {
// use the current hostname as a default
$domain = $_SERVER['SERVER_NAME'];
}
// if the domain name starts with the `www` subdomain
if (substr($domain, 0, 4) === 'www.') {
// strip the subdomain
$domain = substr($domain, 4);
}
// count the dots in the domain name
$numDots = substr_count($domain, '.');
// if there is no dot at all (usually `localhost`) or only a single dot (no subdomain)
if ($numDots < 2) {
// if the domain doesn't already start with a dot
if (substr($domain, 0, 1) !== '.') {
// prepend a dot to allow all subdomains
$domain = '.'.$domain;
}
}
// return the optimized domain name
return $domain;
}
/**
* Creates a random string with the given maximum length
*

View File

@@ -16,15 +16,22 @@
* limitations under the License.
*/
header('Content-type: text/html; charset=utf-8');
// enable error reporting
error_reporting(E_ALL);
ini_set('display_errors', 'stdout');
// enable assertions
ini_set('assert.active', 1);
ini_set('zend.assertions', 1);
ini_set('assert.exception', 1);
header('Content-type: text/html; charset=utf-8');
require __DIR__.'/../vendor/autoload.php';
$db = new PDO('mysql:dbname=php_auth;host=127.0.0.1;charset=utf8mb4', 'root', '');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
require __DIR__.'/../src/Auth.php';
$auth = new \Delight\Auth\Auth($db);
$result = processRequestData($auth);