Лог-он

Все-таки решено интерфейс сделать ввиде симбиоза Flash&html, соотвественно авторизация
будет на html, посредством сессии передаваемой через куки. Код будет на C++.

Алгоритм следующий.
Если переход на страницу требует закрытого доступа, то проверяется кука, если ее нет - то она генериться.
Дальше проверяется в массиве авторизированных кук на наличиее оной, если ее нет - то выдается окно с формой логин/пароль методом POST.
Если происходит POST данных, то проверяется связка логин/пароль и если она верна, кука заноситься в массив.
Также проверяется ИП с которого идет запрос и время последнего действие (время жизни куки).

Для хранения массива кук решено использывать STL multimap с ключом строка-кука.

Ну собственно дальше код:)


TDomTag *cookie=new TDomTag;
parseString(conn[sid].dat->in_Cookie,cookie,';');

strcpy(conn[sid].dat->in_session,cookie->Branch("WI")->Char());//Собственно WI - наша кука
delete cookie;

if (!conn[sid].dat->in_session[0])
{
srand((int)time(0)); //супер-пупер алгоритм генерации новой куки
char temp[512];
for(int i=0;i<10;i++)
{
temp[i]=rand()%2?rand()%26+'A':rand()%26+'a';
temp[i+1]=0;
}
sprintf(conn[sid].dat->out_Cookie,"WI=%s",temp);
strcpy(conn[sid].dat->in_session,temp);
}

TDomTag *post_data=new TDomTag;

if (conn[sid].PostData)
parseString(conn[sid].PostData,post_data);

if (!check_loggon(post_data,sid))
{
delete post_data;
return;
}

int code=200;
if (strncmp(conn[sid].dat->in_RequestURI, "/game", 5)==0)
{
page="Начинаем игру!";
}
else
if (strncmp(conn[sid].dat->in_RequestURI, "/chat", 5)==0){
viewChat(conn[sid].dat->in_RequestURI+5,&page);
}
else
{
code=404;
page="Страница не найдена";
}

и совсем забыл

typedef struct
{
char key[12];
int userid;
time_t update;
char ip[20];
} TSession;

multimap session_list;

bool check_loggon(TDomTag *post_data,int sid)
{
char *form = "тут html код формы с полями Login и Password";

multimap ::iterator i=session_list.find( conn[sid].dat->in_session);

while(i!=session_list.end())
{
if ( i->first != string(conn[sid].dat->in_session))
{
i=session_list.end();
break;
}

if (!strcmp(i->second.ip, conn[sid].dat->in_RemoteAddr))
{
if (time(0)-i->second.update < 10*60*1000)
break;

//сессия устарела
session_list.erase(i);
i=session_list.end();
break;
}

i++;
}

if (i!=session_list.end())
{
//сессия найдена и все ок!
i->second.update = time(0); //update time
return true;
}

if (post_data->Branch("Login")->CharNull())
{
int id=checkUser(post_data->Branch("Login")->Char(),post_data->Branch("Password")->Char());
if (id>0)
{
conn[sid].dat->out_status = 301;
strcpy(conn[sid].dat->out_redirect,"/game/");
TSession s;
strcpy(s.key,conn[sid].dat->in_session);
strcpy(s.ip,conn[sid].dat->in_RemoteAddr);
s.userid=id;
s.update = time(0);
session_list.insert(multimap ::value_type(string(s.key),s));

return false;
}
//пользователь не определен
}

//окно-логина
send_header(sid, 0, 200, "OK", "1", "text/html", -1, -1);
hputs(form);

return false;
}