Fui vendo na internet os tutoriais e tudo mais e resolvi juntar e mais pra frente incrementar meu sisteminha.
Arquivo functions.php
<?php
/**
* Created by PhpStorm.
* User: blx32
* Date: 7/10/16
* Time: 1:58 PM
*/
include_once ('global-config.php');/*
* É importante não colocar apenas "session_start()"; no topo de todas as páginas nas quais você desejar utilizar sessões php, se você realmente estiver preocupado com a segurança, é desta forma que você deverá fazer. Você criará uma função chamada "sec_session_start", a qual irá iniciar uma sessão php de forma segura. Você deveria chamar esta função no topo de cada página a partir da qual você deseje acessar uma variável de sessão php.
Função de Início de Sessão Segura:
*/function sec_session_start(){
$session_name ='sec_session_id';// Set a custom session name
$secure =true;// This stops JavaScript being able to access the session id.
$httponly =true;// Forces sessions to only use cookies.if(ini_set('session.use_only_cookies',1)=== FALSE){
header("Location: ../error.php?err=Could not initiate a safe session (ini_set)");exit();}// Gets current cookies params.
$cookieParams = session_get_cookie_params();
session_set_cookie_params($cookieParams["lifetime"],
$cookieParams["path"],
$cookieParams["domain"],
$secure,
$httponly);// Sets the session name to the one set above.
session_name($session_name);
session_start();// Start the PHP session
session_regenerate_id(true);// regenerated the session, delete the old one.};/*
* Crie uma função de login.
Esta função irá checar o email e a senha na base de dados e retornará um valor "true" (verdadeiro) caso ambos estejam corretos e combinando.
Função de Login Seguro:
*/function login($email, $password, $mysqli){// Using prepared statements means that SQL injection is not possible.if($stmt = $mysqli->prepare("SELECT id, username, password FROM members WHERE email = ? LIMIT 1")){
$stmt->bind_param('s', $email);// Bind "$email" to parameter.
$stmt->execute();// Execute the prepared query.
$stmt->store_result();// get variables from result.
$stmt->bind_result($user_id, $username, $db_password);
$stmt->fetch();if($stmt->num_rows ==1){// If the user exists we check if the account is locked// from too many login attemptsif(checkbrute($user_id, $mysqli)==true){// Account is locked// Send an email to user saying their account is lockedreturnfalse;}else{// Check if the password in the database matches// the password the user submitted. We are using// the password_verify function to avoid timing attacks.if(password_verify($password, $db_password)){// Password is correct!// Get the user-agent string of the user.
$user_browser = $_SERVER['HTTP_USER_AGENT'];// XSS protection as we might print this value
$user_id = preg_replace("/[^0-9]+/","", $user_id);
$_SESSION['user_id']= $user_id;// XSS protection as we might print this value
$username = preg_replace("/[^a-zA-Z0-9_\-]+/","", $username);
$_SESSION['username']= $username;
$_SESSION['login_string']= hash('sha512', $db_password . $user_browser);// Login successful.returntrue;}else{// Password is not correct// We record this attempt in the database
$now = time();
$mysqli->query("INSERT INTO login_attempts(user_id, time) VALUES ('$user_id', '$now')");returnfalse;}}}else{// No user exists.returnfalse;}}};/*
* Função Brute Force.
Ataques de brute force ou força bruta acontecem quando hackers tentam milhares de diferentes senhas em uma conta, seja de forma randômica através de senhas aleatórias ou através de um dicionário de palavras. Em nosso script, se um usuário falhar em sua tentativa de login por mais de 5 vezes, sua conta será bloqueada.
Crie a função login_check:
*/function checkbrute($user_id, $mysqli){// Get timestamp of current time
$now = time();// All login attempts are counted from the past 2 hours.
$valid_attempts = $now -(2*60*60);if($stmt = $mysqli->prepare("SELECT time FROM login_attempts WHERE user_id = ? AND time >'$valid_attempts'")){
$stmt->bind_param('i', $user_id);// Execute the prepared query.
$stmt->execute();
$stmt->store_result();// If there have been more than 5 failed loginsif($stmt->num_rows >5){returntrue;}else{returnfalse;}}}/*Cheque o status de login.
Isto é feito checando-se as variáveis de sessão "user_id" e "login_string". A variável de sessão "login_string" possui as informações de endereço IP e navegador em forma de hash juntamente com a senha. Utilizamos o endereço IP e a informação do navegador pois é muito improvável que o usuário altere o endereço IP ou o navegador durante sua sessão. Fazendo isto, você impede um ataque de hijack na sessão (sequestro de sessão, literalmente).
Crie a função login_check:
*/function login_check($mysqli){// Check if all session variables are set if(isset($_SESSION['user_id'],
$_SESSION['username'],
$_SESSION['login_string'])){
$user_id = $_SESSION['user_id'];
$login_string = $_SESSION['login_string'];
$username = $_SESSION['username'];// Get the user-agent string of the user.
$user_browser = $_SERVER['HTTP_USER_AGENT'];if($stmt = $mysqli->prepare("SELECT password FROM members WHERE id = ? LIMIT 1")){// Bind "$user_id" to parameter.
$stmt->bind_param('i', $user_id);
$stmt->execute();// Execute the prepared query.
$stmt->store_result();if($stmt->num_rows ==1){// If the user exists get variables from result.
$stmt->bind_result($password);
$stmt->fetch();
$login_check = hash('sha512', $password . $user_browser);if(hash_equals($login_check, $login_string)){// Logged In!!!! returntrue;}else{// Not logged in returnfalse;}}else{// Not logged in returnfalse;}}else{// Not logged in returnfalse;}}else{// Not logged in returnfalse;}}function esc_url($url){if(''== $url){return $url;}
$url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\\x80-\\xff]|i','', $url);
$strip = array('%0d','%0a','%0D','%0A');
$url =(string)$url;
$count =1;while($count){
$url = str_replace($strip,'', $url, $count);}
$url = str_replace(';//','://', $url);
$url = htmlentities($url);
$url = str_replace('&','&', $url);
$url = str_replace("'",''', $url);
if ($url[0] !== '/') {
// We're only interested in relative links from $_SERVER['PHP_SELF']return'';}else{return $url;}}?>
autentica_usuario.php
<?php
/**
* Created by PhpStorm.
* User: blx32
* Date: 7/10/16
* Time: 1:35 PM
*/
include_once 'inc/db_connect.php';
include_once 'inc/functions.php';
sec_session_start();// Our custom secure way of starting a PHP session.if(isset($_POST['email'], $_POST['p'])){
$email = $_POST['email'];
$password = $_POST['p'];// The hashed password.if(login($email, $password, $mysqli)==true){// Login success
header('Location: protected_page.php');}else{// Login failed
header('Location: index.php?error=1');}}else{// The correct POST variables were not sent to this page.
echo 'Invalid Request';}
db_connect.php
<?php
/**
* Created by PhpStorm.
* User: blx32
* Date: 7/10/16
* Time: 3:29 PM
*/
include_once 'global-config.php';// As functions.php is not included
$mysqli =new mysqli(HOST, USER, PASSWORD, DATABASE);?>
E global-config.php é onde estão o define do host,user,pdw e database.
register.php
<?php
/**
* Created by PhpStorm.
* User: blx32
* Date: 7/10/16
* Time: 2:20 PM
*//*
* Certifique-se de que o valor de $_POST['p'] já esteja em hash a partir do javascript. Caso não esteja utilizando este método por desejar validar a senha no lado do servidor, certifique-se de utilizar hash.
*/
include_once 'db_connect.php';
include_once 'inc/global-config.php';
$error_msg ="";if(isset($_POST['username'], $_POST['email'], $_POST['p'])){// Sanitize and validate the data passed in
$username = filter_input(INPUT_POST,'username', FILTER_SANITIZE_STRING);
$email = filter_input(INPUT_POST,'email', FILTER_SANITIZE_EMAIL);
$email = filter_var($email, FILTER_VALIDATE_EMAIL);if(!filter_var($email, FILTER_VALIDATE_EMAIL)){// Not a valid email
$error_msg .='<p class="error">The email address you entered is not valid</p>';}
$password = filter_input(INPUT_POST,'p', FILTER_SANITIZE_STRING);if(strlen($password)!=128){// The hashed pwd should be 128 characters long.// If it's not, something really odd has happened
$error_msg .='<p class="error">Invalid password configuration.</p>';}// Username validity and password validity have been checked client side.// This should should be adequate as nobody gains any advantage from// breaking these rules.//
$prep_stmt ="SELECT id FROM members WHERE email = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);// check existing emailif($stmt){
$stmt->bind_param('s', $email);
$stmt->execute();
$stmt->store_result();if($stmt->num_rows ==1){// A user with this email address already exists
$error_msg .='<p class="error">A user with this email address already exists.</p>';
$stmt->close();}}else{
$error_msg .='<p class="error">Database error Line 39</p>';
$stmt->close();}// check existing username
$prep_stmt ="SELECT id FROM members WHERE username = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);if($stmt){
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();if($stmt->num_rows ==1){// A user with this username already exists
$error_msg .='<p class="error">A user with this username already exists</p>';
$stmt->close();}}else{
$error_msg .='<p class="error">Database error line 55</p>';
$stmt->close();}// TODO:// We'll also have to account for the situation where the user doesn't have// rights to do registration, by checking what type of user is attempting to// perform the operation.if(empty($error_msg)){// Create hashed password using the password_hash function.// This function salts it with a random salt and can be verified with// the password_verify function.
$password = password_hash($password, PASSWORD_BCRYPT);// Insert the new user into the databaseif($insert_stmt = $mysqli->prepare("INSERT INTO members (username, email, password) VALUES (?, ?, ?)")){
$insert_stmt->bind_param('sss', $username, $email, $password);// Execute the prepared query.if(! $insert_stmt->execute()){
header('Location: ../error.php?err=Registration failure: INSERT');}}
header('Location: ./register_success.php');}}?>
logoff.php (está escrito errado mas não me preocupei em mudar).
<?php
/**
* Created by PhpStorm.
* User: blx32
* Date: 7/10/16
* Time: 2:14 PM
*/
include_once ('functions.php');
sec_session_start();// Unset all session values
$_SESSION = array();// get session parameters
$params = session_get_cookie_params();// Delete the actual cookie.
setcookie(session_name(),'', time()-42000,
$params["path"],
$params["domain"],
$params["secure"],
$params["httponly"]);// Destroy session
session_destroy();
header('Location: ../index.php');
protegido.php (pagina que quero proteger).
<?php
/**
* Created by PhpStorm.
* User: blx32
* Date: 7/10/16
* Time: 2:32 PM
*/
include_once 'inc/db_connect.php';
include_once 'inc/functions.php';
sec_session_start();?><!DOCTYPE html><html><head><metacharset="UTF-8"><title>Secure Login: Protected Page</title><linkrel="stylesheet"href="styles/main.css"/></head><body><?php if(login_check($mysqli)==true):?><p>Welcome <?php echo htmlentities($_SESSION['username']);?>!</p><p>
This is an example protected page. To access this page, users
must be logged in. At some stage, we'll also check the role of
the user, so pages will be able to determine the type of user
authorised to access the page.
</p><p>Return to <ahref="index.php">login page</a></p><?php else:?><p><spanclass="error">You are not authorized to access this page.</span> Please <ahref="login.php">login</a>.
</p><?php endif;?></body></html>
/**
* Created by blx32 on 7/10/16.
*/function formhash(b,a){var c=document.createElement("input");b.appendChild(c);c.name="p";c.type="hidden";c.value=hex_sha512(a.value);a.value="";b.submit()}function regformhash(f,d,c,b,a){if(d.value==""||c.value==""||b.value==""||a.value==""){alert("You must provide all the requested details. Please try again");returnfalse}e=/^\w+$/;if(!e.test(f.username.value)){alert("Username must contain only letters, numbers and underscores. Please try again");f.username.focus();returnfalse}if(b.value.length<6){alert("Passwords must be at least 6 characters long. Please try again");f.password.focus();returnfalse}var e=/(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}/;if(!e.test(b.value)){alert("Passwords must contain at least one number, one lowercase and one uppercase letter. Please try again");returnfalse}if(b.value!=a.value){alert("Your password and confirmation do not match. Please try again");f.password.focus();returnfalse}var g=document.createElement("input");f.appendChild(g);g.name="p";g.type="hidden";g.value=hex_sha512(b.value);b.value="";a.value="";f.submit();returntrue};
o BD
CREATE DATABASE `secure_login`;
CREATE USER 'sec_user'@'localhost' IDENTIFIED BY 'eKcGZr59zAa2BEWU';
GRANT SELECT, INSERT, UPDATE ON `secure_login`.* TO 'sec_user'@'localhost';
CREATE TABLE `secure_login`.`members`(`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,`username` VARCHAR(30) NOT NULL,`email` VARCHAR(50) NOT NULL,`password` CHAR(128) NOT NULL
) ENGINE =InnoDB;
CREATE TABLE `secure_login`.`login_attempts`(`user_id` INT(11) NOT NULL,`time` VARCHAR(30) NOT NULL
) ENGINE=InnoDB/*
Username: test_user
Email: test@example.com
Password: 6ZaxN2Vzm9NUJT2y
*/
INSERT INTO `secure_login`.`members` VALUES(1,'test_user','test@example.com','$2y$10$IrzYJi10j3Jy/K6jzSLQtOLif1wEZqTRQoK3DcS3jdnFEhL4fWM4G');
A minha duvida é, o que posso fazer para que ele funcione completamente?
Ele loga, e redireciona más na pagina que quero proteger o check_login não funciona muito bem.
Ou como posso adicionar mais a informação "classe" na sessão?
Pergunta
blx32
Fui vendo na internet os tutoriais e tudo mais e resolvi juntar e mais pra frente incrementar meu sisteminha.
Arquivo functions.php
autentica_usuario.php
db_connect.php
E global-config.php é onde estão o define do host,user,pdw e database.
register.php
A pagina login.php
logoff.php (está escrito errado mas não me preocupei em mudar).
protegido.php (pagina que quero proteger).
sha512.js
main.js
o BD
A minha duvida é, o que posso fazer para que ele funcione completamente?
Ele loga, e redireciona más na pagina que quero proteger o check_login não funciona muito bem.
Ou como posso adicionar mais a informação "classe" na sessão?
Desde já agradeço a todos.
Link para o comentário
Compartilhar em outros sites
0 respostass a esta questão
Posts Recomendados
Participe da discussão
Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.