mirror of
https://github.com/delight-im/PHP-Auth.git
synced 2025-08-08 09:06:29 +02:00
Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
27a3990472 | ||
|
1979799480 | ||
|
fff4a59be5 | ||
|
122e2b8006 | ||
|
bebd3efce2 | ||
|
00dc8c3158 | ||
|
e074474955 | ||
|
44907f3489 | ||
|
ea27e8b7d3 |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1 +1,6 @@
|
||||
# IntelliJ
|
||||
.idea/
|
||||
|
||||
# Composer
|
||||
vendor/
|
||||
composer.phar
|
||||
|
1
LICENSE
1
LICENSE
@@ -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
5
NOTICE
Normal 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/).
|
11
README.md
11
README.md
@@ -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
|
||||
|
||||
@@ -254,8 +254,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
|
||||
|
@@ -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.2"
|
||||
},
|
||||
"type": "library",
|
||||
"keywords": [ "auth", "authentication", "login", "security" ],
|
||||
|
99
composer.lock
generated
Normal file
99
composer.lock
generated
Normal 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": "dcde6f2cbd249e6604634f661a6bbcef",
|
||||
"content-hash": "b15a581c89266dd3f30d1a1b92fbe1f1",
|
||||
"packages": [
|
||||
{
|
||||
"name": "delight-im/cookie",
|
||||
"version": "v1.2.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/delight-im/PHP-Cookie.git",
|
||||
"reference": "bac433e605a5879aefc4cd7f35329c3ded2213b5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/delight-im/PHP-Cookie/zipball/bac433e605a5879aefc4cd7f35329c3ded2213b5",
|
||||
"reference": "bac433e605a5879aefc4cd7f35329c3ded2213b5",
|
||||
"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-08 22:01:56"
|
||||
},
|
||||
{
|
||||
"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": []
|
||||
}
|
76
src/Auth.php
76
src/Auth.php
@@ -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
|
||||
*
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user