如何设置Cookie HTTPOnly标志?

问题描述:

如何设置HTTPOnly标志? TCookie没有任何方法或属性来指定HTTPOnly标志。如何设置Cookie HTTPOnly标志?

+3

什么是HTTPOnly标志?什么是TCookie?你的问题缺少**上下文**。 – 2010-05-19 21:42:13

如果你在HttpApp.pas中谈论TCookie,那么就没有内置属性来支持HttpOnly。

你可以看看httpApp.pas在TCookie.GetHeaderValue: string;执行验证。

但是,Cookie只是在标题中设置的,TWebResponse具有CustomHeaders 属性。您可以拨打Response.CustomHeaders.Add(MyCookieValue);

以下类是TCookie的修改版本,用于支持HttpOnly,您可以使用它来正确生成cookie。

unit CookieGen; 

interface 
uses 
Sysutils,Classes,HttpApp; 
type 
    TCookieGenerator = class(TObject) 
    private 
    FName: string; 
    FValue: string; 
    FPath: string; 
    FDomain: string; 
    FExpires: TDateTime; 
    FSecure: Boolean; 
    FHttpOnly: Boolean; 
    protected 
    function GetHeaderValue: string; 
    public 
    property Name: string read FName write FName; 
    property Value: string read FValue write FValue; 
    property Domain: string read FDomain write FDomain; 
    property Path: string read FPath write FPath; 
    property Expires: TDateTime read FExpires write FExpires; 
    property Secure: Boolean read FSecure write FSecure; 
    property HttpOnly : Boolean read FHttpOnly write FHttpOnly; 
    property HeaderValue: string read GetHeaderValue; 
    end; 

implementation 

{ TCookieGenerator } 

function TCookieGenerator.GetHeaderValue: string; 
begin 
    Result := Format('%s=%s; ', [HTTPEncode(FName), HTTPEncode(FValue)]); 
    if Domain <> '' then 
    Result := Result + Format('domain=%s; ', [Domain]); { do not localize } 
    if Path <> '' then 
    Result := Result + Format('path=%s; ', [Path]);  { do not localize } 
    if Expires > -1 then 
    Result := Result + 
     Format(FormatDateTime('"expires="' + sDateFormat + ' "GMT; "', Expires), { do not localize } 
     [DayOfWeekStr(Expires), MonthStr(Expires)]); 
    if Secure then Result := Result + 'secure; '; { do not localize } 
    if HttpOnly then Result := Result + 'HttpOnly'; { do not localize } 
    if Copy(Result, Length(Result) - 1, MaxInt) = '; ' then 
    SetLength(Result, Length(Result) - 2); 

end; 

end. 

到期时>请注意在HTTPApp.pas该原始TCookie.GetHeaderValue()方法可产生一个不正确的报头-1和系统/应用时间分离器比结肠其他符号“:”。 TCookie.GetHeaderValue()方法使用常量sDateFormat格式化“Expires”字段。原来,sDateFormat常数被错误地定义为:

const 
    sDateFormat = '"%s", dd "%s" yyyy hh:nn:ss'; 

如果用户改变该应用程序TimeSeparator中可变比结肠符号以外的东西“:”,则到期时间将使用另一个字符格式化,而不是“ :“按照RFC 1123(格式”Wdy,DD Mon YYYH HH:MM:SS GMT“)的规定。 Google Chrome 25+拒绝使用除冒号以外的时间分隔符的Cookie,导致使用它的网络应用程序完全失败。所以正确的GetHeaderValue()方法应该是:

function TCookieGenerator.GetHeaderValue: string; 
const 
    _DateFormat = '"%s", dd "%s" yyyy hh":"nn":"ss'; // this is the correct constant. HTTPApp.pas wrongly declares it as sDateFormat = '"%s", dd "%s" yyyy hh:nn:ss'; 
begin 
    Result := Format('%s=%s; ', [HTTPEncode(FName), HTTPEncode(FValue)]); 
    if Domain <> '' then 
    Result := Result + Format('domain=%s; ', [Domain]); { do not localize } 
    if Path <> '' then 
    Result := Result + Format('path=%s; ', [Path]);  { do not localize } 
    if Expires > -1 then 
    Result := Result + 
     Format(FormatDateTime('"expires="' + _DateFormat + ' "GMT; "', Expires), { do not localize } 
     [DayOfWeekStr(Expires), MonthStr(Expires)]); 
    if Secure then Result := Result + 'secure; '; { do not localize } 
    if HttpOnly then Result := Result + 'HttpOnly'; { do not localize } 
    if Copy(Result, Length(Result) - 1, MaxInt) = '; ' then 
    SetLength(Result, Length(Result) - 2); 
end; 

我已经提交了关于此的QC#113139。