<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>3. Authentication on BeamFoundry Rays Web Security</title><link>https://rays.bfdy.dev/rays-web-security/docs/3-authentication/</link><description>Recent content in 3. Authentication on BeamFoundry Rays Web Security</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://rays.bfdy.dev/rays-web-security/docs/3-authentication/index.xml" rel="self" type="application/rss+xml"/><item><title>UserDetails Interface</title><link>https://rays.bfdy.dev/rays-web-security/docs/3-authentication/1-user-details/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://rays.bfdy.dev/rays-web-security/docs/3-authentication/1-user-details/</guid><description>&lt;h1 id="1-the-userdetails-interface"&gt;1. The &lt;code&gt;UserDetails&lt;/code&gt; Interface&lt;a class="anchor" href="#1-the-userdetails-interface"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;p&gt;First, adapt your domain model to fulfill the framework&amp;rsquo;s &lt;code&gt;UserDetails&lt;/code&gt; interface, located in &lt;code&gt;pkg/core&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;Note that the framework provides a convenient &lt;code&gt;Authority&lt;/code&gt; string alias to easily generate &lt;code&gt;GrantedAuthority&lt;/code&gt; slice elements.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;models&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; . &lt;span style="color:#e6db74"&gt;&amp;#34;github.com/BeamFoundry/rays-web-security/pkg/core&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;type&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;User&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;ID&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;uint&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Email&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;PasswordHash&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Role&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Implement the UserDetails interface&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;u&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;User&lt;/span&gt;) &lt;span style="color:#a6e22e"&gt;GetUsername&lt;/span&gt;() &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;u&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Email&lt;/span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;u&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;User&lt;/span&gt;) &lt;span style="color:#a6e22e"&gt;GetPassword&lt;/span&gt;() &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;u&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;PasswordHash&lt;/span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;u&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;User&lt;/span&gt;) &lt;span style="color:#a6e22e"&gt;GetAuthorities&lt;/span&gt;() []&lt;span style="color:#a6e22e"&gt;GrantedAuthority&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; []&lt;span style="color:#a6e22e"&gt;GrantedAuthority&lt;/span&gt;{ &lt;span style="color:#a6e22e"&gt;Authority&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;ROLE_&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;u&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Role&lt;/span&gt;) }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// These return false when the account is active and unrestricted&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;u&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;User&lt;/span&gt;) &lt;span style="color:#a6e22e"&gt;IsExpired&lt;/span&gt;() &lt;span style="color:#66d9ef"&gt;bool&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;u&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;User&lt;/span&gt;) &lt;span style="color:#a6e22e"&gt;IsCredentialExpired&lt;/span&gt;() &lt;span style="color:#66d9ef"&gt;bool&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;u&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;User&lt;/span&gt;) &lt;span style="color:#a6e22e"&gt;IsDisabled&lt;/span&gt;() &lt;span style="color:#66d9ef"&gt;bool&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;u&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;User&lt;/span&gt;) &lt;span style="color:#a6e22e"&gt;IsLocked&lt;/span&gt;() &lt;span style="color:#66d9ef"&gt;bool&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>UserDetailsService</title><link>https://rays.bfdy.dev/rays-web-security/docs/3-authentication/2-user-details-service/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://rays.bfdy.dev/rays-web-security/docs/3-authentication/2-user-details-service/</guid><description>&lt;h1 id="2-implementing-userdetailsservice"&gt;2. Implementing &lt;code&gt;UserDetailsService&lt;/code&gt;&lt;a class="anchor" href="#2-implementing-userdetailsservice"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;p&gt;Next, create a Service that implements &lt;code&gt;UserDetailsService&lt;/code&gt;. The framework will automatically detect this Beam and use it during the login process.&lt;/p&gt;&#10;&lt;p&gt;If the user cannot be found, you simply return &lt;code&gt;nil&lt;/code&gt;, and the framework will handle the failed authentication safely.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;security&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; (&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; . &lt;span style="color:#e6db74"&gt;&amp;#34;github.com/BeamFoundry/rays-web-security/pkg/core&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; . &lt;span style="color:#e6db74"&gt;&amp;#34;github.com/BeamFoundry/rays/pkg/core&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; . &lt;span style="color:#e6db74"&gt;&amp;#34;github.com/BeamFoundry/rays/pkg/lang&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;type&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;DomainUserDetailsService&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Service&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;userRepo&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;UserRepository&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`@:&amp;#34;Inject&amp;#34;`&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;s&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;DomainUserDetailsService&lt;/span&gt;) &lt;span style="color:#a6e22e"&gt;LoadUserByUsername&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;username&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;) &lt;span style="color:#a6e22e"&gt;UserDetails&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;userOpt&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;s&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;userRepo&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;FindByEmail&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;username&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Return the user if found&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;user&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;ok&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;userOpt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Get&lt;/span&gt;(); &lt;span style="color:#a6e22e"&gt;ok&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;user&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Return nil if the user does not exist&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Password Encoding</title><link>https://rays.bfdy.dev/rays-web-security/docs/3-authentication/3-password-encoding/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://rays.bfdy.dev/rays-web-security/docs/3-authentication/3-password-encoding/</guid><description>&lt;h1 id="3-password-encoding"&gt;3. Password Encoding&lt;a class="anchor" href="#3-password-encoding"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;p&gt;Never store plain-text passwords. When you boot the application, &lt;code&gt;internal/autoconfig&lt;/code&gt; automatically registers a highly secure, upgradeable default &lt;code&gt;PasswordEncoder&lt;/code&gt;.&lt;/p&gt;&#10;&lt;h2 id="the-delegating-password-encoder"&gt;The Delegating Password Encoder&lt;a class="anchor" href="#the-delegating-password-encoder"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;To support seamless algorithm migrations over time (a best practice from Spring Security), the default encoder is a &lt;code&gt;DelegatingPasswordEncoder&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;It automatically wraps a &lt;code&gt;BCryptPasswordEncoder&lt;/code&gt; (with a cost of 10) mapped to the &amp;ldquo;bcrypt&amp;rdquo; prefix. This means your hashed passwords will automatically be formatted with a prefix, looking something like this:&#10;&lt;code&gt;{bcrypt}$2a$10$wN1FzZ2...&lt;/code&gt;&lt;/p&gt;</description></item><item><title>Remember Me</title><link>https://rays.bfdy.dev/rays-web-security/docs/3-authentication/4-remember-me/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://rays.bfdy.dev/rays-web-security/docs/3-authentication/4-remember-me/</guid><description>&lt;h1 id="4-remember-me-services"&gt;4. Remember Me Services&lt;a class="anchor" href="#4-remember-me-services"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;p&gt;To keep users logged in across browser sessions without relying solely on long-lived session cookies, you can leverage the &lt;code&gt;RememberMeService&lt;/code&gt; interface.&lt;/p&gt;&#10;&lt;p&gt;The framework provides a &lt;code&gt;TokenBasedRememberMeService&lt;/code&gt; in &lt;code&gt;pkg/rememberme&lt;/code&gt;. For a robust enterprise configuration, you should avoid hardcoding secrets and instead use Rays&amp;rsquo; &lt;code&gt;ConfigurationProperties&lt;/code&gt; to load your configuration from YAML.&lt;/p&gt;&#10;&lt;h2 id="configuration-options--defaults"&gt;Configuration Options &amp;amp; Defaults&lt;a class="anchor" href="#configuration-options--defaults"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The &lt;code&gt;TokenBasedRememberMeService&lt;/code&gt; provides several fluent builder methods to customize its behavior:&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th style="text-align: left"&gt;Method&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th style="text-align: left"&gt;Default Value&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th style="text-align: left"&gt;Description&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;&lt;code&gt;WithParameter()&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;&amp;ldquo;remember-me&amp;rdquo;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;The HTML form input checked to determine if the cookie should be set.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;&lt;code&gt;WithCookieName()&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;&amp;ldquo;remember-me&amp;rdquo;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;The name of the cookie sent to the browser.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;&lt;code&gt;WithCookieDomain()&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;&amp;quot;&amp;quot;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;The domain restriction for the cookie.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;&lt;code&gt;WithCookieSecure()&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;false&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;Whether the secure (HTTPS-only) bit should be set on the cookie.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;&lt;code&gt;WithValidity()&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;1209600 (14 days)&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;How long, in seconds, the cookie will be valid.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="example-externalized-configuration"&gt;Example: Externalized Configuration&lt;a class="anchor" href="#example-externalized-configuration"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;First, define your YAML configuration. We explicitly provide the default values here for reference:&lt;/p&gt;</description></item></channel></rss>