webForumDet fria alternativet

Egen tabell för email-verifikation

.NET

20 svar · 1 274 visningar · startad av jaxpax

Medlem sedan aug. 200598 inlägg
Frågan#1

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

Medlem sedan jan. 20023 327 inlägg
#2

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...

Vad tror du om detta?

Medlem sedan aug. 200598 inlägg
#3

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?

Medlem sedan okt. 20041 556 inlägg
#4

Du kan ju använda en tabell med ett replikerings id (guid) i mssql.

Medlem sedan aug. 200598 inlägg
#5

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?

Medlem sedan okt. 20041 556 inlägg
#6

Det är just det jag tänkte på. Ett replikeringsid är ju ganska unikt och svårt att "hitta på" Det kanske räcker att kolla att id-t finns i din tabell.

Medlem sedan aug. 200598 inlägg
#7

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.

Medlem sedan okt. 20041 556 inlägg
#8

Det finns ju lite om detta om man googlar ex. http://www.eggheadcafe.com/articles/20060427.asp
Klipp & klistra :)

Medlem sedan aug. 200598 inlägg
#9

Tack Travioni - ska försöka sätta mig in i det, men det lutar ändå åt en tabell med ett replikerings id.

Medlem sedan nov. 200612 inlägg
#10

Tjena JaxPax ;)

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 :)

//Skurtan

Medlem sedan nov. 20041 189 inlägg
#11

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?

Medlem sedan nov. 200612 inlägg
#12

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.

Medlem sedan aug. 200598 inlägg
#13

Sweet

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.

Top of the day to ya :birp

Medlem sedan dec. 19996 721 inlägg
#14

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)

Medlem sedan nov. 200612 inlägg
#15

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.

Medlem sedan aug. 200598 inlägg
#16

Ahh ok. Aa för mig en något enklare lösning att klara själv :-)

Tack för ditt bidrag emission!!

Medlem sedan nov. 20041 189 inlägg
#17

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.

Medlem sedan aug. 200598 inlägg
#18

Ok...jag trodde att man med hjälp av Roles kunde sätta status för om användaren är aktiverad eller inte. Tack för upplysningen echoSwe!! (y)

Medlem sedan nov. 20041 189 inlägg
#19

Redigerat med anledning av webForums regler §2.
Synpunkter angående detta beslut, ta kontakt med Zaiman alternativt forumledare@webforum.nu.

Zaiman
Moderator, webForum

Medlem sedan sep. 20011 914 inlägg
#20

Håller med emission, ni gör det krångligare än det är.

Obs. Nedan är helt otestat. Utan är bara tänkt att visa själva genomförandet.

1. Skapa ny användare, men sätt IsApproved till false.

MembershipUser newUser = Membership.CreateUser(UsernameTextbox.Text, PasswordTextbox.Text, 
                                                   EmailTextbox.Text, passwordQuestion,
                                                   passwordAnswer, [B]false[/B], out status);

2. Skicka länken till den nya användaren med nyckeln

string key = newUser.ProviderUserKey;
string emaillink = string.Format("http://www.abc.com/approveuser.aspx?key={0}", key);
//Skicka email...

3. Användaren klicka på länken och kommer till en sida där man aktiverar användaren om det ligger inom vald tidsram.

MembershipUser user = Membership.GetUser(Request.QueryString["key"]);

if(user == null)
  return;

DateTime dt1 = user.CreationDate.AddMinutes(30);
DateTime dt2 = DateTime.Now;
if(DateTime.Compare(dt1, dt2) < 0)
{
   user.IsApproved = true;
   Membership.UpdateUser(user);
}
264 ms totalt · 4 externa anrop · v20260731065814-full.a51de22e
127 ms — deklarationer (db)
0 ms — hämta statistik (cache)
134 ms — hämta tråd, inlägg och bilagor (db)
123 ms — ändringar (db)