add support for more cookie flags in Request::AddCookie() method
changed in config options: - renamed: http_session_id_name to session_cookie_name - add config options: session_cookie_path, session_cookie_domain, session_cookie_same_site, session_cookie_http_only, session_cookie_secure
This commit is contained in:
parent
222a1c8a1f
commit
05ecac8426
|
@ -195,7 +195,13 @@ void Config::AssignValues()
|
||||||
use_internal_session_mechanism = Bool(L"use_internal_session_mechanism", true);
|
use_internal_session_mechanism = Bool(L"use_internal_session_mechanism", true);
|
||||||
use_internal_loggin_mechanism = Bool(L"use_internal_loggin_mechanism", true);
|
use_internal_loggin_mechanism = Bool(L"use_internal_loggin_mechanism", true);
|
||||||
|
|
||||||
http_session_id_name = Text(L"http_session_id_name", L"session_id");
|
session_cookie_name = Text(L"session_cookie_name", L"session_id");
|
||||||
|
session_cookie_path = Text(L"session_cookie_path", L"/");
|
||||||
|
session_cookie_domain = Text(L"session_cookie_domain", L"");
|
||||||
|
session_cookie_same_site = Int(L"session_cookie_same_site", 0);
|
||||||
|
session_cookie_http_only = Bool(L"session_cookie_http_only", false);
|
||||||
|
session_cookie_secure = Bool(L"session_cookie_secure", false);
|
||||||
|
|
||||||
db_conn_string = Text(L"db_conn_string");
|
db_conn_string = Text(L"db_conn_string");
|
||||||
db_host = Text(L"db_host");
|
db_host = Text(L"db_host");
|
||||||
db_hostaddr = Text(L"db_hostaddr");
|
db_hostaddr = Text(L"db_hostaddr");
|
||||||
|
|
|
@ -287,7 +287,33 @@ public:
|
||||||
bool use_internal_loggin_mechanism;
|
bool use_internal_loggin_mechanism;
|
||||||
|
|
||||||
// the name of the cookie which has the session identifier
|
// the name of the cookie which has the session identifier
|
||||||
std::wstring http_session_id_name;
|
std::wstring session_cookie_name;
|
||||||
|
|
||||||
|
// session cookie path
|
||||||
|
// default: /
|
||||||
|
std::wstring session_cookie_path;
|
||||||
|
|
||||||
|
// session cookie domain
|
||||||
|
// if empty then the domain will be equal base_url
|
||||||
|
// default: empty
|
||||||
|
std::wstring session_cookie_domain;
|
||||||
|
|
||||||
|
// session cookie samesite attribute
|
||||||
|
// 0 - dont set the attribute
|
||||||
|
// 1 - Strict
|
||||||
|
// 2 - Lax
|
||||||
|
// 3 - None
|
||||||
|
// (values the same as values from CookieSameSite enum)
|
||||||
|
// default: 0
|
||||||
|
int session_cookie_same_site;
|
||||||
|
|
||||||
|
// whether or not set HttpOnly attribute on the session cookie
|
||||||
|
// default: false
|
||||||
|
bool session_cookie_http_only;
|
||||||
|
|
||||||
|
// whether or not set Secure attribute on the session cookie
|
||||||
|
// default: false
|
||||||
|
bool session_cookie_secure;
|
||||||
|
|
||||||
// string used in a place where is a user (or group) selected
|
// string used in a place where is a user (or group) selected
|
||||||
// !! IMPROVE ME should be moved to locales
|
// !! IMPROVE ME should be moved to locales
|
||||||
|
|
|
@ -1646,6 +1646,79 @@ bool is_in_list(const std::wstring & item, const std::set<std::wstring> & list)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void cookie_same_site_to_stream(CookieSameSite same_site, pt::Stream & stream)
|
||||||
|
{
|
||||||
|
switch(same_site)
|
||||||
|
{
|
||||||
|
case CookieSameSite::samesite_strict:
|
||||||
|
stream << L"Strict";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CookieSameSite::samesite_lax:
|
||||||
|
stream << L"Lax";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CookieSameSite::samesite_none:
|
||||||
|
stream << L"None";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void prepare_cookie_string(
|
||||||
|
pt::Stream & cookie,
|
||||||
|
const std::wstring * value_string,
|
||||||
|
const pt::Stream * value_stream,
|
||||||
|
pt::Date * expires,
|
||||||
|
const std::wstring * path,
|
||||||
|
const std::wstring * domain,
|
||||||
|
CookieSameSite cookie_same_site,
|
||||||
|
bool http_only,
|
||||||
|
bool secure)
|
||||||
|
{
|
||||||
|
if( value_string )
|
||||||
|
cookie << *value_string;
|
||||||
|
|
||||||
|
if( value_stream )
|
||||||
|
cookie << *value_stream;
|
||||||
|
|
||||||
|
if( cookie.empty() )
|
||||||
|
cookie << L"\"\""; // cookie empty value
|
||||||
|
|
||||||
|
if( expires )
|
||||||
|
cookie << L"; expires=" << DateToStrCookie(*expires) << L" GMT";
|
||||||
|
|
||||||
|
if( path && !path->empty() )
|
||||||
|
{
|
||||||
|
cookie << L"; path=" << *path;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( domain && !domain->empty() )
|
||||||
|
cookie << L"; domain=" << *domain;
|
||||||
|
|
||||||
|
if( cookie_same_site != CookieSameSite::samesite_notset )
|
||||||
|
{
|
||||||
|
cookie << L"; SameSite=";
|
||||||
|
cookie_same_site_to_stream(cookie_same_site, cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( http_only )
|
||||||
|
cookie << L"; HttpOnly";
|
||||||
|
|
||||||
|
/*
|
||||||
|
don't use '; secure' flag if you are using both sites (with SSL
|
||||||
|
and without SSL) -- with secure flag the cookie is sent only through
|
||||||
|
SSL and if you accidentally open a new window without SSL (http://)
|
||||||
|
then winix will create a new session for you and the previous session (https://)
|
||||||
|
will be lost (the session cookie will be overwritten in the client's browser)
|
||||||
|
*/
|
||||||
|
if( secure )
|
||||||
|
cookie << L"; Secure";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace Winix
|
} // namespace Winix
|
||||||
|
|
||||||
|
|
|
@ -1055,6 +1055,22 @@ bool is_in_list_generic(const std::wstring & item, const ContainerType & list)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void cookie_same_site_to_stream(CookieSameSite same_site, pt::Stream & stream);
|
||||||
|
|
||||||
|
|
||||||
|
void prepare_cookie_string(
|
||||||
|
pt::Stream & out_stream,
|
||||||
|
const std::wstring * value_string = nullptr,
|
||||||
|
const pt::Stream * value_stream = nullptr,
|
||||||
|
pt::Date * expires = nullptr,
|
||||||
|
const std::wstring * path = nullptr,
|
||||||
|
const std::wstring * domain = nullptr,
|
||||||
|
CookieSameSite cookie_same_site = CookieSameSite::samesite_notset,
|
||||||
|
bool http_only = false,
|
||||||
|
bool secure = false);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Winix
|
} // namespace Winix
|
||||||
|
|
||||||
|
|
|
@ -1521,12 +1521,12 @@ void Request::PrepareSessionCookie()
|
||||||
|
|
||||||
if( !session->puser || !session->remember_me )
|
if( !session->puser || !session->remember_me )
|
||||||
{
|
{
|
||||||
AddCookie(config->http_session_id_name, cookie_id_string);
|
AddDefaultSessionCookie(cookie_id_string);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pt::Date expires = start_time + config->session_remember_max_idle;
|
pt::Date expires = start_time + config->session_remember_max_idle;
|
||||||
AddCookie(config->http_session_id_name, cookie_id_string, expires);
|
AddDefaultSessionCookie(cookie_id_string, &expires);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2143,6 +2143,39 @@ void Request::PutMethodName(pt::Stream & stream)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Request::AddCookie(
|
||||||
|
const std::wstring & name,
|
||||||
|
const std::wstring * value_string,
|
||||||
|
const pt::Stream * value_stream,
|
||||||
|
pt::Date * expires,
|
||||||
|
const std::wstring * path,
|
||||||
|
const std::wstring * domain,
|
||||||
|
CookieSameSite cookie_same_site,
|
||||||
|
bool http_only,
|
||||||
|
bool secure)
|
||||||
|
{
|
||||||
|
pt::WTextStream cookie;
|
||||||
|
prepare_cookie_string(cookie, value_string, value_stream, expires, path, domain, cookie_same_site, http_only, secure);
|
||||||
|
out_cookies.add_stream(name, cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Request::AddDefaultSessionCookie(const std::wstring & value, pt::Date * expires)
|
||||||
|
{
|
||||||
|
AddCookie(
|
||||||
|
config->session_cookie_name,
|
||||||
|
&value,
|
||||||
|
nullptr,
|
||||||
|
expires,
|
||||||
|
&config->session_cookie_path,
|
||||||
|
&config->session_cookie_domain,
|
||||||
|
static_cast<CookieSameSite>(config->session_cookie_same_site),
|
||||||
|
config->session_cookie_http_only,
|
||||||
|
config->session_cookie_secure
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Request::FinishRequest()
|
void Request::FinishRequest()
|
||||||
{
|
{
|
||||||
modify_status_code_if_needed(); // will be removed
|
modify_status_code_if_needed(); // will be removed
|
||||||
|
|
|
@ -494,16 +494,18 @@ public:
|
||||||
std::wstring * PostVarp(const wchar_t * var);
|
std::wstring * PostVarp(const wchar_t * var);
|
||||||
std::wstring * PostVarp(const std::wstring & var);
|
std::wstring * PostVarp(const std::wstring & var);
|
||||||
|
|
||||||
|
void AddCookie(
|
||||||
|
const std::wstring & name,
|
||||||
|
const std::wstring * value_string = nullptr,
|
||||||
|
const pt::Stream * value_stream = nullptr,
|
||||||
|
pt::Date * expires = nullptr,
|
||||||
|
const std::wstring * path = nullptr,
|
||||||
|
const std::wstring * domain = nullptr,
|
||||||
|
CookieSameSite cookie_same_site = CookieSameSite::samesite_notset,
|
||||||
|
bool http_only = false,
|
||||||
|
bool secure = false);
|
||||||
|
|
||||||
// setting a cookie
|
void AddDefaultSessionCookie(const std::wstring & value, pt::Date * expires = nullptr);
|
||||||
// name - cookie name (either const wchar_t, or std::wstring or pt::WTextStream)
|
|
||||||
// value - cookie value (can be everything which can be put to pt::WTextStream stream)
|
|
||||||
// the return std::wstring reference is a reference to the cookie inserted value (in out_cookies structure)
|
|
||||||
template<typename NameType, typename ValueType>
|
|
||||||
void AddCookie(const NameType & name, const ValueType & value, pt::Date * expires = 0);
|
|
||||||
|
|
||||||
template<typename NameType, typename ValueType>
|
|
||||||
void AddCookie(const NameType & name, const ValueType & value, pt::Date & expires);
|
|
||||||
|
|
||||||
bool has_frame(const wchar_t * frame);
|
bool has_frame(const wchar_t * frame);
|
||||||
bool has_frame(const std::wstring & frame);
|
bool has_frame(const std::wstring & frame);
|
||||||
|
@ -615,47 +617,6 @@ private:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<typename NameType, typename ValueType>
|
|
||||||
void Request::AddCookie(const NameType & name, const ValueType & value, pt::Date * expires)
|
|
||||||
{
|
|
||||||
pt::WTextStream cookie;
|
|
||||||
|
|
||||||
cookie << value;
|
|
||||||
|
|
||||||
if( cookie.empty() )
|
|
||||||
cookie << L"\"\""; // cookie empty value
|
|
||||||
|
|
||||||
if( expires )
|
|
||||||
cookie << L"; expires=" << DateToStrCookie(*expires) << L" GMT";
|
|
||||||
|
|
||||||
cookie << L"; path=/; domain=" << config->base_url;
|
|
||||||
|
|
||||||
/*
|
|
||||||
!! IMPROVE ME add an option to the config
|
|
||||||
|
|
||||||
don't use '; secure' flag if you are using both sites (with SSL
|
|
||||||
and without SSL) -- with secure flag the cookie is sent only through
|
|
||||||
SSL and if you accidentally open a new window without SSL (http://)
|
|
||||||
then winix will create a new session for you and the previous session (https://)
|
|
||||||
will be lost (the session cookie will be overwritten in the client's browser)
|
|
||||||
*/
|
|
||||||
|
|
||||||
out_cookies.add_stream(name, cookie);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename NameType, typename ValueType>
|
|
||||||
void Request::AddCookie(const NameType & name, const ValueType & value, pt::Date & expires)
|
|
||||||
{
|
|
||||||
AddCookie(name, value, &expires);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Winix
|
} // namespace Winix
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -66,6 +66,10 @@ struct Param
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum CookieSameSite {samesite_notset = 0, samesite_strict = 1, samesite_lax = 2, samesite_none = 3};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// some global types used by Request class
|
// some global types used by Request class
|
||||||
typedef std::map<std::wstring, PostFile> PostFileTab;
|
typedef std::map<std::wstring, PostFile> PostFileTab;
|
||||||
typedef std::vector<Param> ParamTab;
|
typedef std::vector<Param> ParamTab;
|
||||||
|
|
|
@ -479,7 +479,7 @@ Session * SessionManager::PrepareSession()
|
||||||
{
|
{
|
||||||
if( !IsIPBanned() )
|
if( !IsIPBanned() )
|
||||||
{
|
{
|
||||||
CookieTab::iterator i = cur->request->cookie_tab.find(config->http_session_id_name);
|
CookieTab::iterator i = cur->request->cookie_tab.find(config->session_cookie_name);
|
||||||
|
|
||||||
if( i != cur->request->cookie_tab.end() )
|
if( i != cur->request->cookie_tab.end() )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue