mirror of
https://github.com/delight-im/PHP-Auth.git
synced 2025-08-08 09:06:29 +02:00
Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
ab55f7e562 | ||
|
e768243798 | ||
|
27a3990472 | ||
|
1979799480 | ||
|
fff4a59be5 | ||
|
122e2b8006 | ||
|
bebd3efce2 | ||
|
00dc8c3158 | ||
|
e074474955 | ||
|
44907f3489 | ||
|
ea27e8b7d3 |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1 +1,6 @@
|
|||||||
|
# IntelliJ
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
|
# Composer
|
||||||
|
vendor/
|
||||||
|
composer.phar
|
||||||
|
1
LICENSE
1
LICENSE
@@ -199,4 +199,3 @@
|
|||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
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/).
|
15
README.md
15
README.md
@@ -17,8 +17,8 @@ Completely framework-agnostic and database-agnostic.
|
|||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
* PHP 5.5.0+
|
* PHP 5.5.0+
|
||||||
* PDO
|
* OpenSSL extension
|
||||||
* OpenSSL
|
* MySQL 5.5.3+ **or** MariaDB 5.5.23+
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@@ -222,6 +222,10 @@ If the user is not currently signed in, this returns `null`.
|
|||||||
$ip = $auth->getIpAddress();
|
$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
|
### Utilities
|
||||||
|
|
||||||
#### Create a random string
|
#### Create a random string
|
||||||
@@ -254,8 +258,13 @@ $uuid = \Delight\Auth\Auth::createUuid();
|
|||||||
* logout
|
* logout
|
||||||
* full and reliable destruction of session
|
* full and reliable destruction of session
|
||||||
* session management
|
* 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 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
|
* throttling
|
||||||
* per IP address
|
* per IP address
|
||||||
* per account
|
* per account
|
||||||
|
@@ -2,7 +2,9 @@
|
|||||||
"name": "delight-im/auth",
|
"name": "delight-im/auth",
|
||||||
"description": "Authentication for PHP. Simple, lightweight and secure.",
|
"description": "Authentication for PHP. Simple, lightweight and secure.",
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.5.0"
|
"php": ">=5.5.0",
|
||||||
|
"ext-openssl": "*",
|
||||||
|
"delight-im/cookie": "^1.3"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"keywords": [ "auth", "authentication", "login", "security" ],
|
"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": "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": []
|
||||||
|
}
|
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']);
|
session_set_cookie_params($params['lifetime'], $params['path'], $params['domain'], $params['secure'], $params['httponly']);
|
||||||
|
|
||||||
// start the session
|
// start the session
|
||||||
@session_start();
|
@\Delight\Cookie\Session::start();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Improves the application's security over HTTP(S) by setting specific headers */
|
/** 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)
|
* @throws AuthError if an internal problem occurred (do *not* catch)
|
||||||
*/
|
*/
|
||||||
public function login($email, $password, $remember = false) {
|
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;
|
$email = isset($email) ? trim($email) : null;
|
||||||
if (empty($email)) {
|
if (empty($email)) {
|
||||||
throw new InvalidEmailException();
|
throw new InvalidEmailException();
|
||||||
@@ -308,10 +305,16 @@ class Auth {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
$this->throttle(self::THROTTLE_ACTION_LOGIN);
|
||||||
|
$this->throttle(self::THROTTLE_ACTION_LOGIN, $email);
|
||||||
|
|
||||||
throw new InvalidPasswordException();
|
throw new InvalidPasswordException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
$this->throttle(self::THROTTLE_ACTION_LOGIN);
|
||||||
|
$this->throttle(self::THROTTLE_ACTION_LOGIN, $email);
|
||||||
|
|
||||||
throw new InvalidEmailException();
|
throw new InvalidEmailException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -388,7 +391,18 @@ class Auth {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set the cookie with the selector and token
|
// 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) {
|
if ($result === false) {
|
||||||
throw new HeadersAlreadySentError();
|
throw new HeadersAlreadySentError();
|
||||||
@@ -410,7 +424,7 @@ class Auth {
|
|||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
|
|
||||||
// re-generate the session ID to prevent session fixation attacks
|
// 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
|
// save the user data in the session
|
||||||
$this->setLoggedIn(true);
|
$this->setLoggedIn(true);
|
||||||
@@ -456,8 +470,17 @@ class Auth {
|
|||||||
// get our cookie settings
|
// get our cookie settings
|
||||||
$params = $this->createCookieSettings();
|
$params = $this->createCookieSettings();
|
||||||
|
|
||||||
// set the cookie with the selector and token
|
// cause the session cookie to be deleted
|
||||||
$result = setcookie(session_name(), '', time() - 3600, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
|
$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) {
|
if ($result === false) {
|
||||||
throw new HeadersAlreadySentError();
|
throw new HeadersAlreadySentError();
|
||||||
@@ -829,8 +852,6 @@ class Auth {
|
|||||||
// get the default cookie settings
|
// get the default cookie settings
|
||||||
$params = session_get_cookie_params();
|
$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
|
// check if we want to send cookies via SSL/TLS only
|
||||||
$params['secure'] = $params['secure'] || $this->useHttps;
|
$params['secure'] = $params['secure'] || $this->useHttps;
|
||||||
// check if we want to send cookies via HTTP(S) only
|
// check if we want to send cookies via HTTP(S) only
|
||||||
@@ -840,41 +861,6 @@ class Auth {
|
|||||||
return $params;
|
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
|
* Creates a random string with the given maximum length
|
||||||
*
|
*
|
||||||
|
@@ -16,15 +16,22 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
header('Content-type: text/html; charset=utf-8');
|
// enable error reporting
|
||||||
error_reporting(E_ALL);
|
error_reporting(E_ALL);
|
||||||
ini_set('display_errors', 'stdout');
|
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 = new PDO('mysql:dbname=php_auth;host=127.0.0.1;charset=utf8mb4', 'root', '');
|
||||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
|
|
||||||
require __DIR__.'/../src/Auth.php';
|
|
||||||
|
|
||||||
$auth = new \Delight\Auth\Auth($db);
|
$auth = new \Delight\Auth\Auth($db);
|
||||||
|
|
||||||
$result = processRequestData($auth);
|
$result = processRequestData($auth);
|
||||||
|
Reference in New Issue
Block a user