Domanda

Voglio prevenire più accessi in un'applicazione PHP.

Innanzitutto, creo lo stato di accesso (attivo, notato) in una tabella utente.

Quando l'utente, un registro dello stato dell'utente verrà impostato su "attivo" e se l'utente interrompe lo stato impostato su "notact". Quando un altro client trys per accedere utilizzando lo stesso conteggio utente, controllo la tabella utente. Se l'utente è ancora attivo, l'accesso all'errore verrà inviato all'utente.

Si è verificato il problema, se l'utente chiude il browser, lo stato nella tabella utente può essere aggiornato perché l'utente non ha fatto clic su logout.

Hai qualche suggerimento su questo?

È stato utile?

Soluzione

(Si prega di notare che, sebbene la tecnica qui sia ancora in qualche modo valida; i campioni PHP non devono essere copiati alla lettera in quanto esistono mezzi più sicuri per incorporare valori forniti dall'utente in una query SQL)


Invece di archiviare se l'utente è attivo inattivo, è meglio archiviare alcuni attributi che possono essere controllati contro l'utente su base per azione; Come in, ogni volta che l'utente cerca di fare qualcosa che richiede l'autenticazione, verificherà che questo attributo corrisponde prima che proceda.

Ti consiglio di fare quanto segue;

Innanzitutto, crea un hash per identificare in modo univoco l'utente ogni volta che accedono. Immagino che a sha1 di time() sarebbe sufficiente per evitare le collisioni. Qualunque cosa tu scelga, assicurati che sia abbastanza vario in modo che un altro utente l'accesso abbia una probabilità incredibilmente bassa di ricevere lo stesso hash (ad esempio, non hash l'indirizzo IP o l'agente utente del browser, in quanto non sono variati abbastanza).

In secondo luogo, memorizzare questo hash nel tuo database e nell'utente sessione Al momento dell'accesso. In questo modo "disconnetterà effettivamente l'utente precedente, poiché l'hash dovrebbe essere diverso ogni volta che qualcuno accede.

Dal momento che stiamo usando sessioni, un cookie dovrebbe essere automaticamente inserito nel browser dell'utente che conterrà un ID univoco che identifica l'utente ai dati della sessione. Il contenuto del cookie non è davvero preoccupante.

Quindi, crea una funzione chiamata authenticateUser() o simile, che verrà chiamato all'inizio di ogni script per garantire che l'utente sia autenticato. Questo script dovrebbe interrogare il database, verificando se un utente con l'ID dell'utente ha un hash che corrisponde all'hash dell'utente.

Per esempio:

function authenticateUser($id, $hash, $databaseLink) {
    # SQL
    $sql = 'SELECT EXISTS(
               SELECT 1
               FROM `tbl_users`
               WHERE `id` = \''.mysql_real_escape_string($id).'\'
               AND `hash` = \''.mysql_real_escape_string($hash).'\'
               LIMIT 1
           );';

    # Run Query
    if ($query = mysql_query($sql, $databaseLink)) {
        # Get the first row of the results
        # Assuming 'id' is your primary key, there
        # should only ever be one row anyway.       
        $result = mysql_fetch_row($query);

        # Casting to boolean isn't strictly necessary here
        # its included to indicate the mysql result should
        # only ever been 1 or 0.
        return (bool)($result[0]);
    } else {
        # Query error :(
        return false;
    }
}

Quindi, passiamo semplicemente authenticateUser() l'utente ID, hash (per i dati della sessione) e a database link (Per una connessione al database dovrai aver aperto in precedenza).

Se authenticateUser() ritorna true, l'utente è autenticato. Se false, l'utente non è o il database non è disponibile o c'è un errore SQL.

Si prega di notare tuttavia che ciò aumenterà il caricamento del server quando una richiesta di database viene inviata una volta per richiesta di pagina. Probabilmente non è così saggio farlo su progetti giganti in cui migliaia di persone stanno accedendo in qualsiasi momento. Sono sicuro che qualcuno può suggerire miglioramenti.

Inoltre, aspettare che il cookie scada non è il modo migliore per forzare le persone che sono state inattive a disconnettersi, poiché non dovresti mai fidarti dei cookie. Invece, puoi aggiungere una colonna chiamata last_active che puoi aggiornare ogni volta che l'utente viene autenticato. Ciò aumenterà anche il carico del server, ma ti consentirà di sovrascrivere manualmente gli accessi stantii rimuovendo il hash Per gli utenti che sono stati inattivi per 3 ore.

Altri suggerimenti

Ecco una soluzione che no richiedono costante Accesso al database lavorare...

(che eviterà il requisito di controllare la sessione_id () rispetto al valore del database ogni volta che richiedi/aggiorna una pagina, alleviando lo stress DB/server) ...

1. Al login, prendi la sessione preesistente immagazzinata nel DB per questo utente e fai questo:

session_id("the pre-existing session id in the database goes here");
session_start();
session_destroy();

2. Quindi avviare una nuova sessione e salvare questa nuova sessione_id nel database, sovrascrivendo quello precedente. Ciò logoutrà la sessione precedente su questo utente se esiste una attiva (eliminando efficacemente l'altro ragazzo usando questo account).

Provalo e fammi sapere se questo fa il trucco !!

Potresti cambiare il tuo modello in modo che solo l'utente più recente possa essere effettuato l'accesso.

Se si registra l'ID di sessione più recente visualizzato per ciascun utente, quando si accede in una seconda volta è possibile distruggere qualsiasi sessione attualmente esistente, disconnettendoli efficacemente.

Per un utente normale, le cose sembrano "solo funzionare". Se vuoi impedire agli utenti "anormali" di distribuire le loro credenziali di accesso, questo dovrebbe servire da disincentivo.

Quello che dovresti fare è verificare se sono stati attivi negli ultimi minuti quando hanno cercato di accedere. Questo potrebbe essere fatto con un timbro Lasonline e dovrebbe essere impostato su ogni richiesta di pagina nella tabella utente.

Se non hai fatto con JavaScript è possibile verificare, durante l'accesso, se l'utente era attivo negli ultimi 15 minuti. In caso contrario, è possibile accedere come nuovo utente.

Potresti anche farlo con JavaScript. Fai una chiamata Ajax che spara ogni minuto o giù di lì.

<script>
setInterval(function() {
  // do the ajax call
}, 60000);
</script>

Lascia che questa chiamata vada a uno script che modificherà il timbro Lastonline nell'utente DB. Quando si tenta di accedere, si verifica il DB dell'utente se il timbro Lastonline ha superato il minuto e hai il controllo se è possibile accedere. Questo ti aiuterà quando sei sulla pagina ma non sei attivo negli ultimi 15 minuti e non vuoi che qualcun altro accedi.

È necessario creare un ID univoco e archiviarlo in un database. Quello che ho fatto è stato anche creare. Ne memorizzo uno in una variabile di sessione e lo utilizzo per impedire il dirottamento della sessione e un altro in un database per prevenire più accessi. Il seguente codice creerà un ID univoco:

$unique_id = sha1('xzr4'.gethostbyaddr($_SERVER['REMOTE_ADDR']).$random_string.$_SERVER['HTTP_USER_AGENT'].'f8k2');

Se l'ID univoco non corrisponde, si limita semplicemente l'utente.

L'uso del lato client JavaScript per tracciare l'accesso all'utente non è affidabile.

Puoi ottenere lo stesso risultato semplicemente creando un campo LastLogindato nel DB e aggiornandolo con l'ultimo timestamp di accesso dell'utente.

Ad ogni tentativo di accesso, se ora ()-$ lastLogindato> predefinito_timeout, allora dovresti accettare il nuovo accesso, altrimenti rifiutarlo.

Questa soluzione è simile a quella di Prograhammer, ma non richiede di scherzare con sessioni di commutazione. Non richiede di accedere al database su ogni pagina e non bloccano l'utente dopo che non è riuscito a disconnettersi.

Aggiungi un campo per SessionID alla tabella utente nel database.

Imposta il gestore della sessione predefinito prima di chiamare session_start () (necessario per il lavoro successivo di codice):

session_set_save_handler(new \SessionHandler());

Ad ogni accesso riuscito, recuperare $ Sessionid dal database. Distruggi la vecchia sessione con:

(new \SessionHandler())->destroy($sessionID);

Ottieni il nuovo ID sessione con:

$sessionID = session_id();

Archivia il nuovo ID sessione nel database.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top