This commit is contained in:
2018-04-29 21:34:47 -04:00
parent 732065c7b5
commit d8d248672b
23 changed files with 5940 additions and 114 deletions

View File

@@ -1,3 +0,0 @@
DB: lazypugn_LudosData
UserName: lazyp_ludosdata
PassWord: Flqe4&04

File diff suppressed because it is too large Load Diff

View File

@@ -1,21 +1,19 @@
<?php
//error_reporting(E_ALL);
//ini_set('display_errors', 1);
$firstName = $_POST["firstName"];
$lastName = $_POST["lastName"];
$email = $_POST["email"];
$userName = $_POST["userName"];
$password = $_POST["password"];
$newUser = $_POST["newUser"];
$returnData = array();
$date = new DateTime();
$id = $date->getTimestamp() . $userName . $date->getTimestamp();
$id = $date->getTimestamp() . $userName;
$passwordSalt = "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824";
$hashedPassword = crypt( $password, $passwordSalt );
$hashedId = crypt( $id, $passwordSalt );
@@ -38,30 +36,21 @@ $fields = array(
'email' => urlencode( $email ),
'userName' => urlencode( $userName ),
'password' => urlencode( $hashedPassword ),
'id' => urlencode( $hashedId )
'userId' => urlencode( $hashedId ),
'id' => urlencode( $newUser )
);
//url-ify the data for the POST
//foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
//rtrim($fields_string, '&');
$ch = curl_init();
//open connection
$ch = curl_init( $url );
//set the url, number of POST vars, POST data
//curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch,CURLOPT_POSTFIELDS, json_encode($fields));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//execute post
$result = curl_exec( $ch );
//close connection
curl_close( $ch );
echo( $result );
exit();
?>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,34 @@
# PHP-API-AUTH
Single file PHP script that adds authentication to a [PHP-CRUD-API](https://github.com/mevdschee/php-crud-api) project.
## Requirements
- PHP 5.3 or higher
## Simple username + password
On API server
- login.html is loaded
- sends username + password via POST to "api.php/"
- api.php (POST on "/" gets hijacked by auth.php) is loaded
- sends back csrf token + http-only session cookie
- call API as: api.php?csrf=\[csrf token] (session cookie is sent automatically)
- (when using Angular2 or Vue2 the CSRF token is sent automatically)
## With authentication server
On authentication server
- login_token.html is loaded
- sends username + password via POST to "login_token.php"
- login_token.php is loaded
- sends token via POST to "api.php/"
On API server
- api.php (POST on "/" gets hijacked by auth.php) is loaded
- sends back csrf token + http-only session cookie
- call API as: api.php?csrf=\[csrf token] (session cookie is sent automatically)
- (when using Angular2 or Vue2 the CSRF token is sent automatically)

View File

@@ -0,0 +1,34 @@
<?php
// uncomment the lines below when running in stand-alone mode:
// for token+session based authentication (see "login_token.html" + "login_token.php"):
// require 'auth.php';
// $auth = new PHP_API_AUTH(array(
// 'secret'=>'someVeryLongPassPhraseChangeMe',
// ));
// if ($auth->executeCommand()) exit(0);
// if (empty($_SESSION['user']) || !$auth->hasValidCsrfToken()) {
// header('HTTP/1.0 401 Unauthorized');
// exit(0);
// }
// for form+session based authentication (see "login.html"):
// require 'auth.php';
// $auth = new PHP_API_AUTH(array(
// 'authenticator'=>function($user,$pass){ if ($user=='admin' && $pass=='admin') $_SESSION['user']=$user; }
// ));
// if ($auth->executeCommand()) exit(0);
// if (empty($_SESSION['user']) || !$auth->hasValidCsrfToken()) {
// header('HTTP/1.0 401 Unauthorized');
// exit(0);
// }
// include your api code here:
//
// see: https://github.com/mevdschee/php-crud-api
//
// placeholder for testing:
// echo 'Access granted!';

View File

@@ -0,0 +1,223 @@
<?php
//var_dump($_SERVER['REQUEST_METHOD'],$_SERVER['PATH_INFO']); die();
class PHP_API_AUTH {
public function __construct($config) {
extract($config);
$verb = isset($verb)?$verb:null;
$path = isset($path)?$path:null;
$username = isset($username)?$username:null;
$password = isset($password)?$password:null;
$token = isset($token)?$token:null;
$authenticator = isset($authenticator)?$authenticator:null;
$method = isset($method)?$method:null;
$request = isset($request)?$request:null;
$post = isset($post)?$post:null;
$origin = isset($origin)?$origin:null;
$time = isset($time)?$time:null;
$leeway = isset($leeway)?$leeway:null;
$ttl = isset($ttl)?$ttl:null;
$algorithm = isset($algorithm)?$algorithm:null;
$secret = isset($secret)?$secret:null;
$allow_origin = isset($allow_origin)?$allow_origin:null;
// defaults
if (!$verb) {
$verb = 'POST';
}
if (!$path) {
$path = '';
}
if (!$username) {
$username = 'username';
}
if (!$password) {
$password = 'password';
}
if (!$token) {
$token = 'token';
}
if (!$method) {
$method = $_SERVER['REQUEST_METHOD'];
}
if (!$request) {
$request = isset($_SERVER['PATH_INFO'])?$_SERVER['PATH_INFO']:'';
if (!$request) {
$request = isset($_SERVER['ORIG_PATH_INFO'])?$_SERVER['ORIG_PATH_INFO']:'';
}
}
if (!$post) {
$post = 'php://input';
}
if (!$origin) {
$origin = isset($_SERVER['HTTP_ORIGIN'])?$_SERVER['HTTP_ORIGIN']:'';
}
if (!$time) {
$time = time();
}
if (!$leeway) {
$leeway = 5;
}
if (!$ttl) {
$ttl = 30;
}
if (!$algorithm) {
$algorithm = 'HS256';
}
if ($allow_origin===null) {
$allow_origin = '*';
}
$request = trim($request,'/');
$this->settings = compact('verb', 'path', 'username', 'password', 'token', 'authenticator', 'method', 'request', 'post', 'origin', 'time', 'leeway', 'ttl', 'algorithm', 'secret', 'allow_origin');
}
protected function retrieveInput($post) {
$input = (object)array();
$data = trim(file_get_contents($post));
if (strlen($data)>0) {
if ($data[0]=='{') {
$input = json_decode($data);
} else {
parse_str($data, $input);
$input = (object)$input;
}
}
return $input;
}
protected function generateToken($claims,$time,$ttl,$algorithm,$secret) {
$algorithms = array('HS256'=>'sha256','HS384'=>'sha384','HS512'=>'sha512');
$header = array();
$header['typ']='JWT';
$header['alg']=$algorithm;
$token = array();
$token[0] = rtrim(strtr(base64_encode(json_encode((object)$header)),'+/','-_'),'=');
$claims['iat'] = $time;
$claims['exp'] = $time + $ttl;
$token[1] = rtrim(strtr(base64_encode(json_encode((object)$claims)),'+/','-_'),'=');
if (!isset($algorithms[$algorithm])) return false;
$hmac = $algorithms[$algorithm];
$signature = hash_hmac($hmac,"$token[0].$token[1]",$secret,true);
$token[2] = rtrim(strtr(base64_encode($signature),'+/','-_'),'=');
return implode('.',$token);
}
protected function getVerifiedClaims($token,$time,$leeway,$ttl,$algorithm,$secret) {
$algorithms = array('HS256'=>'sha256','HS384'=>'sha384','HS512'=>'sha512');
if (!isset($algorithms[$algorithm])) return false;
$hmac = $algorithms[$algorithm];
$token = explode('.',$token);
if (count($token)<3) return false;
$header = json_decode(base64_decode(strtr($token[0],'-_','+/')),true);
if (!$secret) return false;
if ($header['typ']!='JWT') return false;
if ($header['alg']!=$algorithm) return false;
$signature = bin2hex(base64_decode(strtr($token[2],'-_','+/')));
if ($signature!=hash_hmac($hmac,"$token[0].$token[1]",$secret)) return false;
$claims = json_decode(base64_decode(strtr($token[1],'-_','+/')),true);
if (!$claims) return false;
if (isset($claims['nbf']) && $time+$leeway<$claims['nbf']) return false;
if (isset($claims['iat']) && $time+$leeway<$claims['iat']) return false;
if (isset($claims['exp']) && $time-$leeway>$claims['exp']) return false;
if (isset($claims['iat']) && !isset($claims['exp'])) {
if ($time-$leeway>$claims['iat']+$ttl) return false;
}
return $claims;
}
protected function allowOrigin($origin,$allowOrigins) {
if (isset($_SERVER['REQUEST_METHOD'])) {
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Expose-Headers: X-XSRF-TOKEN');
foreach (explode(',',$allowOrigins) as $o) {
if (preg_match('/^'.str_replace('\*','.*',preg_quote(strtolower(trim($o)))).'$/',$origin)) {
header('Access-Control-Allow-Origin: '.$origin);
break;
}
}
}
}
protected function headersCommand() {
$headers = array();
$headers[]='Access-Control-Allow-Headers: Content-Type, X-XSRF-TOKEN';
$headers[]='Access-Control-Allow-Methods: OPTIONS, GET, PUT, POST, DELETE, PATCH';
$headers[]='Access-Control-Allow-Credentials: true';
$headers[]='Access-Control-Max-Age: 1728000';
if (isset($_SERVER['REQUEST_METHOD'])) {
foreach ($headers as $header) header($header);
} else {
echo json_encode($headers);
}
}
public function hasValidCsrfToken() {
$csrf = isset($_SESSION['csrf'])?$_SESSION['csrf']:false;
if (!$csrf) return false;
$get = isset($_GET['csrf'])?$_GET['csrf']:false;
$header = isset($_SERVER['HTTP_X_XSRF_TOKEN'])?$_SERVER['HTTP_X_XSRF_TOKEN']:false;
return ($get == $csrf) || ($header == $csrf);
}
public function executeCommand() {
extract($this->settings);
if ($origin) {
$this->allowOrigin($origin,$allow_origin);
}
if ($method=='OPTIONS') {
$this->headersCommand();
return true;
}
$no_session = $authenticator && $secret;
if (!$no_session) {
ini_set('session.cookie_httponly', 1);
session_start();
if (!isset($_SESSION['csrf'])) {
if (function_exists('random_int')) $_SESSION['csrf'] = 'N'.random_int(0,PHP_INT_MAX);
else $_SESSION['csrf'] = 'N'.rand(0,PHP_INT_MAX);
}
}
if ($method==$verb && trim($path,'/')==$request) {
$input = $this->retrieveInput($post);
if ($authenticator && isset($input->$username) && isset($input->$password)) {
$authenticator($input->$username,$input->$password);
if ($no_session) {
echo json_encode($this->generateToken($_SESSION,$time,$ttl,$algorithm,$secret));
} else {
session_regenerate_id();
setcookie('XSRF-TOKEN',$_SESSION['csrf'],0,'/');
header('X-XSRF-TOKEN: '.$_SESSION['csrf']);
echo json_encode($_SESSION['csrf']);
}
} elseif ($secret && isset($input->$token)) {
$claims = $this->getVerifiedClaims($input->$token,$time,$leeway,$ttl,$algorithm,$secret);
if ($claims) {
foreach ($claims as $key=>$value) {
$_SESSION[$key] = $value;
}
session_regenerate_id();
setcookie('XSRF-TOKEN',$_SESSION['csrf'],0,'/');
header('X-XSRF-TOKEN: '.$_SESSION['csrf']);
echo json_encode($_SESSION['csrf']);
}
} else {
if (!$no_session) {
session_destroy();
}
}
return true;
}
return false;
}
}

View File

@@ -0,0 +1,5 @@
<form method="post" action="api.php/">
<input name="username" value="admin"/>
<input name="password" value="admin"/>
<input type="submit" value="ok">
</form>

View File

@@ -0,0 +1,5 @@
<form method="post" action="login_token.php">
<input name="username" value="admin"/>
<input name="password" value="admin"/>
<input type="submit" value="ok">
</form>

View File

@@ -0,0 +1,13 @@
<form method="post" action="api.php/">
<input name="token" value=
<?php
require 'auth.php';
$auth = new PHP_API_AUTH(array(
'secret'=>'someVeryLongPassPhraseChangeMe',
'authenticator'=>function($user,$pass){ if ($user=='admin' && $pass=='admin') $_SESSION['user']=$user; }
));
$auth->executeCommand();
?>/>
<input type="submit" value="ok">
</form>

View File

@@ -0,0 +1,3 @@
<form method="post" action="api.php/">
<input type="submit" value="logout">
</form>

View File

@@ -1,4 +0,0 @@
<?php
?>

View File

@@ -1,4 +0,0 @@
<?php
?>

View File

@@ -1,60 +1,32 @@
<form novalidate (ngSubmit)="onSubmit(form.value)" [formGroup]="form" >
<div class="lrContainer">
<mat-card class="lrCard">
<mat-card-header>
<mat-card-title>
<h2>Login</h2>
</mat-card-title>
</mat-card-header>
<div class="lrContainer">
<mat-card class="lrCard">
<mat-card-header>
<mat-card-title>
<h2>Login</h2>
</mat-card-title>
</mat-card-header>
<mat-form-field class="fullWidth">
<input matInput placeholder="Username"
[formControlName]="'userName'"
[id]="'userName'"
[type]="'text'"
[name]="'userName'">
</mat-form-field>
<mat-form-field class="fullWidth">
<input matInput placeholder="Username"
[formControlName]="'userName'"
[id]="'userName'"
[type]="'text'"
[name]="'userName'">
</mat-form-field>
<mat-form-field class="fullWidth">
<input matInput placeholder="Password"
[formControlName]="'password'"
[id]="'password'"
[type]="'password'"
[name]="'password'">
</mat-form-field>
<mat-form-field class="fullWidth">
<input matInput placeholder="Password"
[formControlName]="'password'"
[id]="'password'"
[type]="'password'"
[name]="'password'">
</mat-form-field>
<button type="submit" mat-raised-button color="primary" [disabled]="!form.valid">Login</button>
<button mat-button [routerLink]="['/register']" >Register</button>
<button type="submit" mat-raised-button color="primary" [disabled]="!form.valid">Login</button>
<button mat-button [routerLink]="['/register']" >Register</button>
</mat-card>
</div>
</form>
<!--
<div class="col-md-6 col-md-offset-3">
<h2>Login</h2>
<form name="form" (ngSubmit)="f.form.valid && login()" #f="ngForm" novalidate>
<div class="form-group" [ngClass]="{ 'has-error': f.submitted && !username.valid }">
<label for="username">Username</label>
<input type="text" class="form-control" name="username" [(ngModel)]="model.username" #username="ngModel" required />
<div *ngIf="f.submitted && !username.valid" class="help-block">Username is required</div>
</div>
<div class="form-group" [ngClass]="{ 'has-error': f.submitted && !password.valid }">
<label for="password">Password</label>
<input type="password" class="form-control" name="password" [(ngModel)]="model.password" #password="ngModel" required />
<div *ngIf="f.submitted && !password.valid" class="help-block">Password is required</div>
</div>
<div class="form-group">
<button [disabled]="loading" class="btn btn-primary">Login</button>
<img *ngIf="loading" src="data:image/gif;base64,R0lGODlhEAAQAPIAAP///wAAAMLCwkJCQgAAAGJiYoKCgpKSkiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQJCgAAACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkECQoAAAAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkECQoAAAAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkECQoAAAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQJCgAAACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQJCgAAACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAkKAAAALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA==" />
<a [routerLink]="['/register']" class="btn btn-link">Register</a>
</div>
</form>
</div>
-->
</mat-card>
</div>
</form>

View File

@@ -1,6 +1,7 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { FormBuilder, FormGroup, FormControl, Validators } from '@angular/forms';
import { RegistrationService } from '../registration.service';
@Component({
@@ -16,8 +17,9 @@ export class LoginComponent implements OnInit {
constructor(
private route: ActivatedRoute,
private router: Router
) { }
private router: Router,
private registrationService: RegistrationService
) { }
ngOnInit() {
// reset login status
@@ -51,6 +53,20 @@ export class LoginComponent implements OnInit {
return formValidators;
}
onSubmit( form ){
this.registrationService.loginUser( form ).subscribe( data => {
//this.router.navigate([this.returnUrl]);
console.log( "valid" );
},
error => {
console.log( "you suck, no long for you!" );
//this.alertService.error(error);
//this.loading = false;
});
}
login() {
/*
this.loading = true;

View File

@@ -21,7 +21,8 @@ export class RegisterComponent implements OnInit {
private registrationService: RegistrationService,
private usernameValidator: UsernameValidator,
private emailValidator: EmailValidator,
public formBuilder: FormBuilder
public formBuilder: FormBuilder,
public router : Router
){ }
@@ -67,8 +68,7 @@ export class RegisterComponent implements OnInit {
onSubmit( form ){
this.registrationService.createNewUser( form ).subscribe( data => {
console.log(data);
//this.router.navigateByUrl("/login");
this.router.navigateByUrl("/login");
});
}

View File

@@ -12,9 +12,8 @@ const httpOptions = {
export class RegistrationService {
APIURL = "http://192.241.155.78/api.php";
registrationUrl = "http://192.241.155.78/registrationCreation.php";
/* Needed for post, could be moved to local method variable */
registrationUrl = "http://192.241.155.78/interfaceServices/registrationInterface.php/users/";
login Url = "http://192.241.155.78/interfaceServices/loginInterface.php/users/";
params;
constructor(
@@ -41,15 +40,26 @@ export class RegistrationService {
createNewUser( userData ): Observable<any>{
/* needed for content-type x-www */
this.params = new HttpParams({
fromObject: userData
});
return this.http.post( this.registrationUrl, this.params, httpOptions )
.map(res => {
console.log(res)
return(
res
);
});
}
loginUser( userData ): Observable<any>{
this.params = new HttpParams({
fromObject: userData
});
return this.http.get( this.loginUrl, this.params, httpOptions )
.map(res => {
return(
res
);

View File

@@ -17,20 +17,11 @@ export class EmailValidator {
return new Promise(resolve => {
this.debouncer = setTimeout(() => {
this.registrationService.validateEmail(control.value).subscribe((res) => {
console.log(res.users.length)
if(res.users.length === 0){
resolve(null);
}else{
resolve({'emailInUse': true});
}
/*
if(res.ok){
resolve(null);
}
}, (err) => {
resolve({'usernameInUse': true});
*/
});
}, 1000);
});

View File

@@ -17,19 +17,11 @@ export class UsernameValidator {
return new Promise(resolve => {
this.debouncer = setTimeout(() => {
this.registrationService.validateUserName(control.value).subscribe((res) => {
console.log(res.users.length)
if(res.users.length === 0){
resolve(null);
}else{
resolve({'usernameInUse': true});
}
/*
if(res.ok){
resolve(null);
}
}, (err) => {
resolve({'usernameInUse': true});
*/
});
}, 1000);