Vinnaren i pepparkakshustävlingen!
2016-10-07, 09:46
  #1
Medlem
ArzeniXs avatar
Hej,

Har en fråga till er experter. Jag har en hemsida där jag har tänkt göra åtkomsten av en specifik fil lösenordsskyddad. För att hålla det relativt enkelt är det inte supernödvändigt att sökvägen till filen hålls hemlig på webbhotellet efter att användaren angivit rätt lösenord. Det är mer tänkt som en enklare skydd för obehöriga.

Jag provade först med följande lösning som jag hittade här


där jag satte en enkel scriptfunktion som öppnade en ny tab till den angivna filen efter det att användaren angivit rätt lösenord. Detta fungerade utmärkt på min Apache server men inte på webbhotellet (one.com). Problemet på one.com är att den inte vill skicka mig vidare till den angivna filen utan istället uppdaterar sidan och tvingar mig att ange lösenordet igen.

Jag har lite erfarenhet av PHP sedan tidigare så om någon vill skicka mig i rätt riktning så ska jag nog kunna lösa resten själv. Tack.
__________________
Senast redigerad av ArzeniX 2016-10-07 kl. 09:50.
Citera
2016-10-07, 11:52
  #2
Medlem
Bongomans avatar
Lösning: Byt till ett seriöst webbhotell som har fler metoder för AUTH installerade. Man kompilerar inte in en massa "onödiga" moduler när man har priser under tian i månaden.
Citera
2016-10-07, 19:10
  #3
Medlem
Om du inte verkligen måste ha filen på webbhotellet så kan du lagra den i en annan tjänst som har skydd out-of-the-box.
Google Drive - Du kan dela en länk och så får varje person begära access.
Mega - Dela en länk och skicka ut nyckeln till alla personer som behöver access.

Finns säkert många fler tjänster som gör det minst lika bra. Jag använder ovanstående.
Citera
2016-10-08, 18:56
  #4
Medlem
enowens avatar
Du kan generera en url med en nyckel som är giltig i cirka 10 minuter, via den länken så läser du innehållet i filen och skriver ut den till den specifika url'en med rätt encoding osv.

Ingen har tillgång till den riktiga filen, urlen är alltid giltig några få minuter och det genereras nya url'er hela tiden och lagras i en databas.

För att göra det säkrare så slänger du in i din htaccess fil så att man inte kan komma åt filen direkt heller.
Citera
2016-10-08, 22:25
  #5
Medlem
XSendFile förtjänar att nämnas också, för fullständighetens skull, även om inte alla stödjer den, tyvärr..
T.ex http://codeutopia.net/blog/2009/03/0...dfile-and-php/
Citera
2016-10-09, 05:48
  #6
Medlem
enowens avatar
Slängde ihop detta snabbt, för att du ska få en hint om hur du kan lösa det.
Skapa alla dessa filer:

database.config.php

Kod:
<?php
$config 
= array(
    
'host' => 'localhost',
    
'username' => 'admin',
    
'password' => 'pass',
    
'database' => 'download',
    
'charset' => 'utf8'
);

example.txt

Citat:
Skriv vad du vill i den filen, detta är filen som ska vara gömd

hidden.php

Kod:
<?php
session_start
();
if (!isset(
$_SESSION['userId'])) {
    die(
'You are not logged in');
}
require(
'database.config.php');
$dsn 'mysql:host=' $config['host'] . ';dbname=' $config['database'] . ';';
$options = array(
    
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'",
    
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
$pdo null;
try {
    
$pdo = new PDO($dsn$config['username'], $config['password'], $options);
    if (!empty(
$_GET['id'])) {
        
$stmt $pdo->prepare('SELECT path FROM url WHERE id = :id AND date_expires > NOW()');
        
$stmt->execute(array('id' => $_GET['id']));
        
$fileName $stmt->fetchColumn();

        
/**
         * Rewrite this to read chunks of the file
         * also put the correct content type
         */
        
if ($fileName) {
            
$myfile fopen($fileName"r") or die("Unable to open file!");
            echo 
fread($myfilefilesize($fileName));
            
fclose($myfile);
        }
        else {
            echo 
'Invalid link, either expired or it does not exist';
        }
    }
    else {
        echo 
'No id given';
    }
}
catch (
PDOException $ex) {
    echo 
$ex->getMessage();
}

index.php

Kod:
<?php
session_start
();
if (!isset(
$_SESSION['userId'])) {
    if (!empty(
$_GET['action']) && $_GET['action'] == 'login') {
        
/**
         * Check if user can login, we set the test user id for now
         */
        
$_SESSION['userId'] = 1;
        
header('location: index.php');
    }
?>
    <form action="index.php?action=login" method="post">
    <input type="text" name="" placeholder="username">
    <input type="text" name="" placeholder="password">
    <input type="submit" value="Log in">
    </form>
<?php
}
else {
    if (!empty(
$_GET['action']) && $_GET['action'] == 'showurl') {
        echo 
'Visit this link, its valid for 10 minutes: <a href="' $_GET['url'] . '">' $_GET['url'] . '</a>';
    }
    else {
        require(
'database.config.php');
        
$dsn 'mysql:host=' $config['host'] . ';dbname=' $config['database'] . ';';
        
$options = array(
            
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'",
            
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
        
);
        
$pdo null;
        try {
            
$pdo = new PDO($dsn$config['username'], $config['password'], $options);
            
$stmt $pdo->prepare(
                
'INSERT INTO url (id, userid, path, date_created, date_expires) VALUES (:id, :userid, :path, NOW(), NOW() + INTERVAL 10 MINUTE)'
            
);
            
$somewhatUniqueId uniqid(); // fix your own unique id, this is shit
            
$stmt->execute(array('id' => $somewhatUniqueId'userid' => $_SESSION['userId'], 'path' => 'example.txt'));
            
header('location: index.php?action=showurl&url=hidden.php?id=' $somewhatUniqueId);
        }
        catch (
PDOException $ex) {
            echo 
$ex->getMessage() . '<hr>';
            echo 
'Make sure you run the install.php file';
        }
    }
}
?>

install.php

Kod:
<?php
require('database.config.php');

$setupQuery[] = "CREATE DATABASE " $config['database'] . ";";
$setupQuery[] = "
CREATE TABLE `" 
$config['database'] . "`.`url` (
    `id` VARCHAR(255) NOT NULL,
    `userid` INT NOT NULL,
    `path` VARCHAR(255) NOT NULL,
    `date_created` DATETIME NOT NULL,
    `date_expires` DATETIME NOT NULL,
    PRIMARY KEY (
        `id`, `userid`
    )
) ENGINE = InnoDB;
"
;
$setupQuery[] = "
CREATE TABLE `" 
$config['database'] . "`.`user` (
    `id` INT NOT NULL AUTO_INCREMENT ,
    `username` VARCHAR(50) NOT NULL ,
    `password` VARCHAR(255) NOT NULL ,
    PRIMARY KEY (
        `id`
    ),
    UNIQUE (
        `username`
    )
) ENGINE = InnoDB;
"
;
$insertQuery[] = "INSERT INTO `user` (username, password) VALUES ('test', 'test')";

$dsn 'mysql:host=' $config['host'] . ';';
$options = array(
    
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'",
    
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
$pdo null;
try {
    
$pdo = new PDO($dsn$config['username'], $config['password'], $options);
}
catch (
PDOException $ex) {
    echo 
'Failed to connect to server: ' $ex->getMessage();
}
$pdo->beginTransaction();
try {
    foreach (
$setupQuery as $query) {
        
$pdo->query($query);
    }
    
$pdo->commit();
    
$pdo->exec('use ' $config['database']);
    foreach (
$insertQuery as $query) {
        
$pdo->query($query);
    }
    echo 
'Successfully installed database';
}
catch (
PDOException $ex) {
    echo 
'Failed to install database: ' $ex->getMessage();
}

Kör install.php så att alla tabeller osv skapas.
Sedan går du till index.php och bara klickar på login. Detta får du fixa själv men tabellen finns. Du kommer då få en länk som fungerar i 10 minuter där du kan se example.txt filen.

Du får skriva detta snyggt och du kan även använda en .htaccess fil för att verkligen se till att ingen kan läsa din example.txt direkt via någon sökvägen.
Citera

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback