Vid nyregistrering av ett medlemskap kan man låta den nya medlemmen verifiera sitt medlemskap via en länk som man automatiskt genererar och skickar till den nya medlemmens emailadress. Då måste ju länken bestå av en unik adress!
Är det då bäst att skapa en tabell i db som genererar en unik nyckel specifikt för detta ändamål? :q
Man skulle väll kunna använda det unika medlemsid:et men jag föreställer mig att detta kanske skulle kunna vara dåligt ur säkerhetssynpunkt då medlemsid:et ju förekommer i flera tabeller som FK? :q
Har jag rätt i detta: att skapa en unik nyckel i en egen tabell för just "email_verification"? :q
Jag ser ingen osäkerhet att använda detta ID som nyckel i adressen om dina sida är implementerad på ett säkert sätt. En annan variant skulle ju vara att du använder detta id och en egen lite hemlig algoritm som du kör när du genererar adressen. Säg att du har en funktion som tar ett id som parameter och genererar nyckeln till en URL. Sedan har du en funktion som tar denna nyckel som parameter och retunerar rätt ID. En lättare form av kryptering där du inte behöver lägga till något ytterligare attribut i din tabell...
Kanon. Av det lilla jag vet inom ämnet så låter det som en bättre idé. Går det att använda någon inbyggd krypteringsfunktion i SQL server, exempelvis med hashing?
Ok! Är jag helt ute och cyklar om jag påstår att det liknar det tillvägagångssätt jag själv var inne på. En ny "email_verification" tabell med medlemsid som FK?
Just...kolla att det finns där och att matcha det mot rätt FK (som i detta fallet är medlemsid). Tror nog att det får bli något sådant. Compusas förslag vore nice men jag har nog inte rätt kunskapsnivå för att skapa en krypteringsfunktion.
Jag kan tänka mig flertalet sätt att göra detta, men om du helst vill komma undan att skapa nya tabeller eller kolumner. Du skulle ju i din user-tabell kunna skapa en kolumn för "activation" som innehåller 0 eller en kod beroende på om användaren är aktiverad eller inte. Du måste ju hursomhelst någonstans lagra om användaren är aktiverad.
Vill du på ett annat sätt aktivera användaren utan att visa en massa information, gör exempelvis så här:
När du skickar mailet till användaren kan du hasha email+id som bör vara unikt.
string minHemligaKod = FormsAuthentication.HashPasswordForStoringInConfigFile(email + id, "SHA1");
Urlen som användaren klickar på bör innehålla id och ovanstående genererad sträng: ex. validera.aspx?id=<id>&kod=<minHemligaKod>
Validera.aspx bör då göra en "select id, email from user" och använda dessa för att generera sha1 krypterade strängen igen för att sedan jämföra dem genom:
if (request.querystring["kod"] == FormsAuthentication.HashPasswordForStoringInConfigFile(email + id, "SHA1"))
{
valideraAnvändare(request.querystring["id"]);
}
visst skulle någon kunna lista ut vad du bygger strängen på, men kasta in något annat i HashPasswordForStoringInConfigFile från användarens data som inte är känsligt så blir det väldigt bökigt. För att ytterligare spä på det kan du använda dig av ett SHA-salt, dvs om email och id verkar ytterst enkelt att komma på ... lägg till en valfri sträng, t:ex "bill666gates" + email + id som du sedan även använder vid jämförelsen.
Om MSSQL har den här formen av hashning inbyggt vet jag ej, mySql har ett antal inbyggda funktioner, AES/DES/MD5/SHA, det bör finnas i MSSQL likväl.
Vill du ha mer info så vet du hur du får tag på mig :)
Har samma "problem", men jag använde Guids redan från början så det var inget problem... Min fråga är snarare hur ni har löst timeout på Reset Password och Create New User Verification, då länkarna i princip inte borde gå att klicka på hur länge som helst och Reset Password ska bara fungera en gång...
Jag kan naturligtvis skapa en tabell med förfrågningar - mail skickade - och uppdatera den när ett mail har sin länk klickad på, men nån annan som har en über lösning?
När det gäller hur länge länken ska fungera har jag en fundering, inte nödvändigtvis någon lösning:
Jag kan tänka mig en tvåvägskrypterad kod som även innehåller den formen av info om man inte vill lagra infon. Återigen så kan man ju knäcka en sådan kod förr eller senare, men jag vill se den f*n som lägger ner åtskilliga dagar/veckor/månader/år för att få registrera sig för sent ;) Se t:ex http://www.codeproject.com/dotnet/DotNetCrypto.asp
I praktiken bygga en sträng med i ditt fall guid<avskiljare>timeoutdatum och kryptera det hela. När du löser ut strängen ifrån urlrequesten kollar du datumet.
Timeout på reset password är samma procedur antar jag, men att länken bara skall fungera en gång är en annan femma. En flagga i databasen är väl det snyggaste. Tänk efter om det inte är något annat fält som faktiskt "betyder" att användaren inte loggat in tidigare (sen länken använts). Fullösning är att lagra det nya lösenordet, med en tvist, dvs lägga till något till lösenordet som kontrolleras och tas bort när användaren senare loggar in.
Tack för ett riktigt utförligt svar Crypth. :bire
Ur säkerhetssynpunt tilltalas jag starkt av att kunna kryptera informationen så därför är detta ett starkt argument för att nappa på ditt förslag. När det gäller huruvida man kan lagra för att avgöra om användaren är aktiverad eller inte skulle man iofs kunna använda sig av en del smaskig funktionalitet i ASP.NET 2.0, dvs med hjälp av "Roles" i Membership Provider. Men denna funktionalitet verkar tyvärr inte kunna erbjuda den säkerhet som ett förslag med kryptering. Japp den utförliga beskrivningen får mig att vilja försöka köra på med kryptering.
Tackar ödmjukast, Crypth och alla ni andra som bidrog till en intressant diskusion.
Värst vad ni knepar till det.. Kryptering är helt irrelevant i ett dylikt case.
I usertabellen:
userId eller ännu hellre confirmationId som Guid (skickas med i länken)
en kolumn som flaggar konfirmeringsstatus (avgör status)
en kolumn som anger när mailet skickades. (avgör om det är för sent)
emission, helt riktigt, det är ju den direkta enkla lösningen. Dock förstod jag det som att nya fält i databasen var att undvika.
En sidenote till:
Kryptering vid lagrande av lösenord i databasen är att rekommendera, skulle någon komma över dem, är de oanvändbara om man använder sig av en stark kryptering eller ett rejält salt.
Crypth: Du borde inte lagra lösenorden krypterat, eftersom man då får tillgång till alla lösenord om man hittar krypteringslösenordet, dvs då blir alla lösenord beroende på ditt enda. Dessutom måste du då spara lösenordet i filer som accessar databasen vilket leder till att det blir ännu mer osäkert.
Hasha dem istället, det är inte kryptering, och lägg på ett salt. Det behöver inte vara ett rejält salt alls, eftersom det enbart är brute-force med rainbow tables man ska skydda sig mot.
Roles innehållet inte det du säger Japax. Det du menar är Membership. Jfr. RoleProvider och MembershipProvider i ASP.Net, samt klassen Roles och klassen Membership som är de klasserna som använder sig of the providers.