Gå til innhold

passord og skrapekort


Anbefalte innlegg

Er det vanskelig å lage et php passord-generator-script som matcher passord på et skrapekort?

Litt sånn som nettbanker fungerer med skrapekort eller kodebrikke.

 

En passordgenerator forstår jeg hvordan jeg lager, men hvordan blir disse kodene matchet til koden på et kort?

 

Noen som vet om noen tutorials for dette?

Evt. artikler etc...?

Lenke til kommentar
  • 2 uker senere...
Videoannonse
Annonse

Heisann Demiurgen.

Det hjelper å vite hva dette skal brukes til, eller mer spesifikk informasjon rundt det hele.

 

Slik jeg forstår det:

Du ønsker at denne koden skal personen motta på en webside?

 

Nå ønsker du at koden bare fungerer i X tid, etter mottat.

- Hvorfor? (kan bli nødvendig info)

 

Denne koden skal også matche noe, slik en faktisk vet at den ikke er falsk/feil.

 

 

Dette lar seg gjøre, ganske simpelt, men du blir nødt til å bruke cron-jobb. Jeg tror du heller skal sjekke dette opp på javaforumet, da java er MYE bedre egenet for slik som dette. PHP er ikke dynamisk, så når personen har mottatt koden, så vil vi ikke kunne ha oppdatert databasen (med tidsfristen lagret, samt koden).

 

Som vil da si: Om klienten ikke velger å refrashe etter at tiden er løpt ut, så vil han/hun kunne benytte seg av koden.

Det er her cronjob er nødvendig, som sjekker databasen hvert 10. min, og ser om noen koder er utgått.

 

 

Videre kommer det ann på bruk:

Om brukeren skal kunne gjøre noe inne i dette kodegrensesnittet, så må koden være lagret som en cookie (alà et innloggingscript), og koden må ikke dø ut/slettes etter med det første, altså du vil trenge at koden er valid i noen timer (kommer iallefall ann på hva det gjelder), evt en funksjon for å si at koden er i bruk i nåtid. Kan kreve enda en cronjob.

 

 

Altså gir du spesifikk info her så kan jeg garantere at noen hjelper til, om det ikke viser seg å bli en tungvindt, eller idiotisk oppgave. :b

Men, jeg vil tro at java gjør dette enda bedre. (=

Endret av tROOP4H
Lenke til kommentar

Takk for svar.

 

Jeg tenkte å bruke det til en e-lærings nettjeneste.

Brukerne får utdelt fysiske kort i papir med mange koder på. (Da kan jeg kanskje ha reklame/sponsorer på kortet - ellers vil sms være et alternativ)

Når de skal logge seg på får de beskjed om å skrape fram f.eks. kode nr 16 og logge seg inn med den i tillegg til vanlig brukernavn og passord. - akkurat som en nettbank egentlig.

 

Jeg håper å finne en enkel måte å lage et slikt system på med php/mysql. Java, C, o.l. blir litt for hardcore for meg.

Lenke til kommentar

Tja, da må du vel egentlig lage en generator som generer koder til bestemmte nummer, og legge dette til i en database. Så lager du kortene med kodene på, og når man skal skrive inn koden sjekker du om koden stemmer overns med nummeret man blir bett om å skrape.

Lenke til kommentar

Ingenting av dette er vanskeligere å gjøre i PHP enn noe annet språk og er ganske enkelt.

 

Enkelt og greit:

 

-Lag et normalt brukernavn/passord system

-Generer X antall koder for hver bruker.

-Hver gang bruker skal logge inn kreves brukernavn, passord og første ubrukte kode.

-Koden blir flagget som brukt ved bruk eller nok feil forsøk.

-Dersom brukeren har brukt opp alle sine koder må nye koder genereres.

Lenke til kommentar

Detaljene rundt implementasjon er helt opp til deg selv. Ingen fasit her :)

 

Det enkleste vil nok være å generere en rekke tilfeldige koder (som passer dine kriterier), for deretter å lagre det i en database.

 

 

Tabelloppsettet kan f.eks. se slik ut:

Id - KodeIDen.

UserID - Hvilke bruker koden tilhører.

FieldID - Hvilke felt på gjeldene kodeark koden tilsvarer. Når brukeren ber om nytt kodeark er det bare å slette oppføringene til det gamle, da selv om det fins ubrukte koder på det ønsker man ikke å ha det i omløp av sikkerhetsmessige grunner.

Generated/BatchID - Når den er generert - eventuellt ID til hvilke batch koder. (Ingen vits i å ha denne om du ikke vil slette gamle koder)

Invalidated - Når den ble brukt. Eventuell en umulig dato dersom koden ble invalidert uten å bli brukt. Eventuellt kan du bare slette oppføringen når den blir brukt, dersom du ikke har behov for å gå gjennom invaliderte koder senere.

Data - Koden.

 

Bare det første som popper opp i hodet mitt, sikkert ikke helt passende da du nok har andre behov enn det jeg kommer på på sparket.

Lenke til kommentar

users

id, int, pk

username, string, unique

salt, string

hash, string

 

pins

id, int, pk

user_id, int, pk

pin, int

num_errors, int, 0

date_used, datetime, 0

 

public function generateKeysForUser($userId, $numberOfNewKeys)

{

$sql = "SELECT MAX(id) FROM pins WHERE user_id = {$userId};";

$max =

$sql = "INSERT INTO pins (id, user_id, pin) VALUES";

for ($i = 0; $i < $numberOfNewKeys; $i++) {

$sql .= " ( " . $max + $i + 1 . ", {$userId}, " . rand(0, 9999) . " ),";

}

$sql = substr($sql, 0, -1);

// Insert SQL

}

 

"SELECT id, pin FROM pins WHERE user_id = {$userId} WHERE !date_used ORDER BY id ASC LIMIT 1;

"UPDATE pins SET date_used = NOW() WHERE id = {$pinId} AND user_id = {$userId};";

Endret av JohndoeMAKT
Lenke til kommentar
Når de skal logge seg på får de beskjed om å skrape fram f.eks. kode nr 16 og logge seg inn med den i tillegg til vanlig brukernavn og passord. - akkurat som en nettbank egentlig.

Host hark, akkurat som MinID, som er veldig vanlig i offentlige tjenester.

 

Sikkherhet rundt kodene, og litt frihet på hvordan du ønsker de generert, kan bli gjort med denne funkjsonen:

 

Jeg vil annbefale å ta ibruk metoden John Doe viser til, men om du ønsker mer sikre passord, så kan dette være et alternetiv for å skape pins.

function create_pins($length=8,$use_upper=1,$use_lower=1,$use_number=1){
$upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$lower = "abcdefghijklmnopqrstuvwxyz";
$number = "0123456789";
if($use_upper){
	$seed_length += 26;
	$seed .= $upper;
}
if($use_lower){
	$seed_length += 26;
	$seed .= $lower;
}
if($use_number){
	$seed_length += 10;
	$seed .= $number;
}
for($x=1;$x<=$length;$x++){
	$pins .= $seed{rand(0,$seed_length-1)};
}
return($pins);
}

$pins = create_pins(10,1,1,1); //10 tall/bokstaver, aktiver upper, aktiver lower, aktiver tall.

echo $pins; //returnerer f. eks xD3rw03L7c

 

Hvordan matche case-sensitive til databasen:

mysql_query("SELECT * FROM din_tabell WHERE pins LIKE BINARY '$pins'");

Endret av tROOP4H
Lenke til kommentar

Takk igjen for bra svar.

Veldig bra funksjon for å generere pin-koder tROOP4H.

 

Jeg har satt opp databasen slik JohndoeMAKT foreslo. Foreløpig bare med en bruker som har bruker id 1. jeg har også generert 25 pin-koder i den andre tabellen, alle med user_id 1.

 

Nå trenger jeg litt hjelp til SQL-n, for å slå de to tabellene sammen (for jeg må vel det?)

Jeg har følgende sql nå:

$sql = "SELECT id, username FROM users WHERE username = '{$username}' AND hashed_password = '{$hashed_password}' LIMIT 1";

 

Hvordan får jeg inn pin-koden her slik at den også må matche?

Lenke til kommentar

Du bør ikke sjekke passord i samme SQL som du henter bruker med. Hvordan vet du da at brukeren ikke kan logge inn fordi brukernavnet er feil eller at passordet er feil?

 

Ytelsesmessig kan det være best å hente dette ut i to-tre spørringer, men la oss høre på Knuth og fikse det på sikt.

 

SELECT u.id, u.username, u.salt, u.hash, p.id AS pin_id, p.pin FROM users AS u LEFT JOIN pins AS p ON ( u.id = p.user_id ) WHERE u.id = {$userId} AND !p.date_used AND p.num_errors < 3 ORDER BY p.id ASC LIMIT 1;

Lenke til kommentar

Den virker for å slå de sammen. Jeg får da en tabell med info fra de to tabellene.

Men den sql-n jeg bruker så er det jo det brukernavnet og passordet som skrives inn som ligger i WHERE klausulen og ikke bruker_id.

Mulig jeg bare er dum nå men jeg forstår ikke hvordan brukerens id kan komme inn her.

 

jeg poster liksågreit hele php koden her med den gamle sql-n kommentert ut:

<?php 
require_once("inc/session.php");
require_once("inc/connection.php");
require_once("inc/functions.php");

if (logged_in()) {
redirect_to("index.php");
}

include_once("inc/form_functions.php");

// START FORM PROCESSING
if (isset($_POST['submit'])) { // Form has been submitted.
$errors = array();

// perform validations on the form data
$required_fields = array('username', 'password');
$errors = array_merge($errors, check_required_fields($required_fields, $_POST));

$fields_with_lengths = array('username' => 30, 'password' => 30);
$errors = array_merge($errors, check_max_field_lengths($fields_with_lengths, $_POST));

$username = trim(mysql_prep($_POST['username']));
$password = trim(mysql_prep($_POST['password']));
$hashed_password = sha1($password);
$code = trim(mysql_prep($_POST['code']));

if ( empty($errors) ) {

	//New sql.
	$query = "SELECT u.id, u.username, u.hashed_password, p.id AS pin_id, p.pin FROM grim_users AS u LEFT JOIN grim_pins AS p ON ( u.id = p.user_id ) WHERE u.id = 1 AND !p.date_used AND p.num_errors < 3 ORDER BY p.id ASC LIMIT 1;";

	// Check database to see if username and the hashed password exist there.
	/*$query = "SELECT id, username ";
	$query .= "FROM grim_users ";
	$query .= "WHERE username = '{$username}' ";
	$query .= "AND hashed_password = '{$hashed_password}' ";
	#$query .= "AND code = '{$code}' ";
	$query .= "LIMIT 1";*/

	$result_set = mysql_query($query);
	confirm_query($result_set);
	if (mysql_num_rows($result_set) == 1) {
		// username/password authenticated
		// and only 1 match
		$found_user = mysql_fetch_array($result_set);
		$_SESSION['user_id'] = $found_user['id'];
		$_SESSION['username'] = $found_user['username'];

		redirect_to("index.php");
	} else {
		// username/password combo was not found in the database
		$message = "Username/password combination incorrect.<br />
			Please make sure your caps lock key is off and try again.";
	}
} else {
	if (count($errors) == 1) {
		$message = "There was 1 error in the form.";
	} else {
		$message = "There were " . count($errors) . " errors in the form.";
	}
}

} else { // Form has not been submitted.
if (isset($_GET['logout']) && $_GET['logout'] == 1) {
	$message = "You are now logged out.";
} 
$username = "";
$password = "";
$code = "";
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="css/main.css" />
<title>Grim</title>
</head>

<body>
<div id="login">
<h1>Login</h1>
<?php if (!empty($message)) {echo "<p class=\"error\">" . $message . "</p>";} ?>
<?php if (!empty($errors)) { display_errors($errors); } ?>
<form action="login.php" method="post">
<p><label for="username">Username</label></p>
<p><input id="username" type="text" name="username" maxlength="30" value="<?php echo htmlentities($username); ?>" /></p>
<p><label for="password">Password</label></p>
<p><input id="password" type="password" name="password" maxlength="30" value="<?php echo htmlentities($password); ?>" /></p>
<p><label for="code">Code</label></p>
<p><input id="code" type="password" name="code" maxlength="6" value="<?php echo htmlentities($code); ?>" /></p>
<p><input id="login_btn" type="submit" name="submit" value="Login" /></p>
</form>
</div>
</body>
</html>

Lenke til kommentar

Ikke at jeg har lest gjennom koden du publiserte, noe som vil ta meg noen minutter, brukte tiden på å lage en kode som kansje hjelper, om jeg forsto problemet...? :p

 

//Dette er ikke en kode, men men en forenklet fremgangsmåte. 
<?php
//Dette er ikke en kode, men men en forenklet fremgangsmåte. 
function validate($user, $pass, $pin) {
$userSql = "SELECT * FROM grim_users WHERE username='$user' and password='$pass'";
$userRes = mysql_query($userSql);
$user    = mysql_num_rows($userRes);
$getUser = mysql_fetch_array($result);

if($user==1){
	$id       = $getUser['user_id'];
	$pinsSql  = "SELECT * FROM grim_pins WHERE user_id='$id' and pins LIKE BINARY '$pin'";
	$pinsRes  = mysql_query($pinsSql);
	$pins     = mysql_num_rows($pinsRes);
	if($pins==1) {
		$res = "Valid";
		//Skal vi slette brukte pins? -->
		mysql_query(DELETE FROM grim_pins WHERE pins LIKE BINARY '$pins' AND user_id='$id');
	} 
	elseif($pins!=1) {
		$res = "Invalid pin!";
	}
}
elseif($user!=1) {
	$res = "Invalid Username or Password!";
}
return($res);
}

if(isset($_POST['submit'])) {
$username = $_POST['username'];
$password = md5($_POST['password']);
$pin      = $_POST['pin']; //Case-Sensitive
$validate = validate($username, $password, $pin);
if ($validate == "Valid") {
	/*
	--> registrer session
	--> Og alt annet tull du trenger! 
	*/
} 
else {
	echo $validate;
	/*
	--> Evt gi ut annen feilmelding...
	*/
}
}
?>
<HTML>POSTFELT</HTML>

 

Jeg formoder at du forstår diverse endringer må bli gjort, integrering er nødvendig.. Etc... Dette skal ikke være så vanskelig som du gjør det til, og skjønner helt egentlig ikke problemstillingen.

 

--> Brukerdatabasen inneholder brukernavn, bruker_id og password.

--> Pindatabase inneholder pins, og bruker_id som den tilhører.

 

Utpå dette så bygger vi et script som først matcher om brukeren eksisterer, derreter så matcher vi om pins eksisterer, alt dette skjer i fuksjonen jeg har vist til ovenfor. Den skal ikke være nødvendig å redigere mye...

 

Derimot så er det nødvedig med diverse sikkerhetstiltak.. Slik du har i din kode.

--> Nå som dette steget først er forstått, og integrert, så kan du utvide.

Endret av tROOP4H
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...