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_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_host = Text(L"db_host");
|
||||
db_hostaddr = Text(L"db_hostaddr");
|
||||
|
|
|
@ -287,7 +287,33 @@ public:
|
|||
bool use_internal_loggin_mechanism;
|
||||
|
||||
// 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
|
||||
// !! 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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1521,12 +1521,12 @@ void Request::PrepareSessionCookie()
|
|||
|
||||
if( !session->puser || !session->remember_me )
|
||||
{
|
||||
AddCookie(config->http_session_id_name, cookie_id_string);
|
||||
AddDefaultSessionCookie(cookie_id_string);
|
||||
}
|
||||
else
|
||||
{
|
||||
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()
|
||||
{
|
||||
modify_status_code_if_needed(); // will be removed
|
||||
|
|
|
@ -494,16 +494,18 @@ public:
|
|||
std::wstring * PostVarp(const wchar_t * 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
|
||||
// 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);
|
||||
void AddDefaultSessionCookie(const std::wstring & value, pt::Date * expires = nullptr);
|
||||
|
||||
bool has_frame(const wchar_t * 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
|
||||
|
||||
#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
|
||||
typedef std::map<std::wstring, PostFile> PostFileTab;
|
||||
typedef std::vector<Param> ParamTab;
|
||||
|
|
|
@ -479,7 +479,7 @@ Session * SessionManager::PrepareSession()
|
|||
{
|
||||
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() )
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue