<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="88814" data-post-id="88814">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="OvermindDL1" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/OvermindDL1/120/2677_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  OvermindDL1
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="31" data-topic="4731">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>Note that <a href="https://www.owasp.org/index.php/SameSite" rel="noopener nofollow ugc">SameSite </a> may make cookies safe once again but we are probably a couple years away still.</p>
</blockquote>
</aside>
<blockquote>
<p>As of November 2017 the SameSite attribute is implemented in Chrome, Firefox, and Opera.</p>
</blockquote>
<p>Oh hey!  That’s why I’ve been seeing <code>lax</code> and <code>strict</code> things on cookies on sites lately!</p>
<p>We’d definitely want a way to use different cookies, one lax and one strict for sure, different session types!!!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="88814" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/accessing-cookies-in-phoenix-socket-connect/4731/32">Post #31</a>
	                </div>
	            </div>
              <div id="likers-container-88814" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="88814"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #31"></div>
  </section>
</div>
    <div class="postbit" id="88849" data-post-id="88849">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="yurko" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/yurko/120/2369_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  yurko
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="OvermindDL1" data-post="24" data-topic="4731">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/overminddl1/48/2677_2.png" class="avatar"> OvermindDL1:</div>
<blockquote>
<p>Has phoenix messed up the check origin configuration? As I recall it takes explicit site domains or to be entirely disabled (which absolutely should not be default of course).</p>
</blockquote>
</aside>
<p>I does, though if you have a public WS API (and if you have native apps as clients, you have to) you must disable the origin check.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="88849" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/accessing-cookies-in-phoenix-socket-connect/4731/33">Post #32</a>
	                </div>
	            </div>
              <div id="likers-container-88849" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="88849"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #32"></div>
  </section>
</div>
    <div class="postbit" id="88920" data-post-id="88920">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="OvermindDL1" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/OvermindDL1/120/2677_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  OvermindDL1
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="yurko" data-post="33" data-topic="4731">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/yurko/48/2369_2.png" class="avatar"> yurko:</div>
<blockquote>
<p>(and if you have native apps as clients, you have to)</p>
</blockquote>
</aside>
<p>No you don’t, just specify an origin in the library you use, every native websocket client library I’ve touched yet (5 while I was testing) have an option to specify the origin.  <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="88920" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/accessing-cookies-in-phoenix-socket-connect/4731/34">Post #33</a>
	                </div>
	            </div>
              <div id="likers-container-88920" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="88920"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #33"></div>
  </section>
</div>
    <div class="postbit" id="89006" data-post-id="89006">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="yurko" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/yurko/120/2369_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  yurko
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Hm, I used React Native with Phoenix Socket library (technically not a native ws lib) and didn’t see such an option, here are the ones the can be specified <a href="https://github.com/mspanc/phoenix_socket/blob/master/dist/socket.js#L590-L617" class="inline-onebox" rel="noopener nofollow ugc">phoenix_socket/dist/socket.js at master · mspanc/phoenix_socket · GitHub</a> maybe it would work as a key in params?</p>
<p>Anyway the way I see it is an origin that we can freely control can also be controlled by a malicious 3rd party so it doesn’t add much in terms of security.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="89006" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/accessing-cookies-in-phoenix-socket-connect/4731/35">Post #34</a>
	                </div>
	            </div>
              <div id="likers-container-89006" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="89006"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #34"></div>
  </section>
</div>
    <div class="postbit" id="89051" data-post-id="89051">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="OvermindDL1" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/OvermindDL1/120/2677_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  OvermindDL1
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>You aren’t allowed to control the origin header from inside the web browser sandbox as per the standard, hence why a web browser javascript library doesn’t expose such an option.  <img src="https://forum.elixirforum.com/images/emoji/apple/wink.png?v=15" title=":wink:" class="emoji" alt=":wink:" loading="lazy" width="20" height="20"></p>
<p>The origin header is to control web browser security, if you are in native code then you could easily just scrape a webpage to get a token (potentially even grabbing the web browsers cookie or whatever else) and then feed that in to the live websocket, so none of that security matters anyway for native code (hence why you should build a proper auth system if you need auth regardless, but the browser should be able to store that auth in a cookie backed by an origin as that is the way the standard was written).</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="89051" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/accessing-cookies-in-phoenix-socket-connect/4731/36">Post #35</a>
	                </div>
	            </div>
              <div id="likers-container-89051" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="89051"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #35"></div>
  </section>
</div>
    <div class="postbit" id="89084" data-post-id="89084">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="yurko" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/yurko/120/2369_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  yurko
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="OvermindDL1" data-post="36" data-topic="4731">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/overminddl1/48/2677_2.png" class="avatar"> OvermindDL1:</div>
<blockquote>
<p>so none of that security matters anyway for native code</p>
</blockquote>
</aside>
<p>pretty much what I meant as well <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="89084" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/accessing-cookies-in-phoenix-socket-connect/4731/37">Post #36</a>
	                </div>
	            </div>
              <div id="likers-container-89084" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="89084"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #36"></div>
  </section>
</div>
    <div class="postbit" id="236760" data-post-id="236760">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="marinho10" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/marinho10/120/33692_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  marinho10
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>The best explanation is here:</p>
<p><a href="https://medium.com/coletiv-stories/using-websockets-with-cookie-based-authentication-7e4bb9262898" class="onebox" target="_blank" rel="noopener nofollow ugc">https://medium.com/coletiv-stories/using-websockets-with-cookie-based-authentication-7e4bb9262898</a></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="236760" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/accessing-cookies-in-phoenix-socket-connect/4731/38">Post #37</a>
	                </div>
	            </div>
              <div id="likers-container-236760" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="236760"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #37"></div>
  </section>
</div>
    <div class="postbit" id="241409" data-post-id="241409">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="knightq" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/knightq/120/25590_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  knightq
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<blockquote>
<p>Exactly my point, hence why it should be stored in the cookie.</p>
</blockquote>
<p>For example, for what JWT is designed for.</p>
<p>I’ve carefully read all the concerns about security (I agree with), BUT I think you are just considering scenarios in which the same Phoenix backend is both the authentication service AND the websocket endpoint.</p>
<p>I want to suggest you another scenario, for which the suggested workaround of using a csrf token from the Phoenix backend won’t be possible.</p>
<p>Let’s say we have these services:</p>
<p>A - <a href="http://login.somesite.com" rel="noopener nofollow ugc">login.somesite.com</a>: Ruby on Rails (or whatever you prefer) backend that has the responsibility to Authenticate user (= to return a jwt token, in response to a login request, through a HttpOnly, secure, SameSite strict)<br>
B - <a href="http://www.somesite.com" rel="noopener nofollow ugc">www.somesite.com</a>: another (micro)service that renders tha app and manges the Business logics.<br>
C - <a href="http://communications.somesite.com" rel="noopener nofollow ugc">communications.somesite.com</a>: the Phoenix (micro)service that handles WS Communications.</p>
<p>If you prefer, B &amp; C might be the same service, no matter.</p>
<p>Service A sends a signed JWT HttpOnly cookie on domain “.somesite.com”, so that each services can exploit a decentralized authentication / verification, without the need of asking A (of course, that’s the way JWT has been designed for).<br>
The wss protocol used to open a bidirectional channel, as you pointed out, allow us to send that jwt cookie to the C service (Phoenix) too, without the need to make the jwt accessible to the JS (it would open a way more dangerous security problem, if we woudn’t have that cookie “HttpOnly”).</p>
<p>Here, unfortunatly, comes the Phoenix backend with its design choices, that prevent us from reading that cookie (that wss protocol would let us send), making it useless.</p>
<p>I agree with the concerns that having a secure first design approach is in general a good choice, but in this case:</p>
<ul>
<li>Developer has one secure way to prevent the security risk (CSWSH), simply by enforcing the Origin checks on server side.</li>
<li>Developer has no way to access the cookie, since the framework has chosen to deny its access.</li>
</ul>
<p>I would have prefered - in these cases - a “smart config” approach, if you care so much about CSWSH risk, where developers can - through an opt-in choice in server configuration - choose to have the cookie available in the connection endpoint.</p>
<p>What do you think about?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="241409" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/accessing-cookies-in-phoenix-socket-connect/4731/39">Post #38</a>
	                </div>
	            </div>
              <div id="likers-container-241409" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="241409"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #38"></div>
  </section>
</div>
    <div class="postbit" id="271085" data-post-id="271085">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="spence" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/spence/120/28789_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  spence
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>We can get access to the <code>user_token</code> natively by copying LiveView’s approach (CSRF):</p>
<pre data-code-wrap="elixir"><code class="lang-elixir"># lib/web/endpoint.ex
@session_options [ ... ]

socket "/socket", Web.UserSocket, websocket: [connect_info: [{:session, @session_options}]]
</code></pre>
<pre data-code-wrap="javascript"><code class="lang-javascript">// assets/app.js
let csrf_token = /* get via `csrf_meta_tag()` or `csrf_token_value()` */
let socket = new Socket("/socket", {params: {_csrf_token: csrf_token}});
</code></pre>
<pre data-code-wrap="elixir"><code class="lang-elixir"># lib/web/channels/user_socket.ex
def connect(_params, socket, %{session: session}) do
  if user_token = Map.get(session, "user_token") do
    user = Account.get_user_by_session_token(user_token)
    {:ok, assign(socket, :user, user)}
  else
    :error
  end
end
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="271085" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/accessing-cookies-in-phoenix-socket-connect/4731/40">Post #39</a>
	                </div>
	            </div>
              <div id="likers-container-271085" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="271085"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #39"></div>
  </section>
</div>
    <div class="postbit" id="363285" data-post-id="363285">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="andreyvolokitin" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/andreyvolokitin/120/35974_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  andreyvolokitin
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><code>SameSite</code> <a href="https://caniuse.com/same-site-cookie-attribute" rel="noopener nofollow ugc">looks available to browsers for quite some time</a>. Does it change situation regarding the possibility of optionally using cookies for authentification in websockets? (even as web-specific option not available for possible custom transports)</p>
<p>Also, how could banning the user be implemented when using a token-based socket authentification? <a href="http://cryto.net/%7Ejoepie91/blog/2016/06/19/stop-using-jwt-for-sessions-part-2-why-your-solution-doesnt-work/" rel="noopener nofollow ugc">It looks to be problematic</a></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="363285" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/accessing-cookies-in-phoenix-socket-connect/4731/41">Post #40</a>
	                </div>
	            </div>
              <div id="likers-container-363285" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="363285"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #40"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/4731/load_more?page=5">Load more posts (3 remaining)</a>
</div></template></turbo-stream>