text: Title: Implement browser session API
  Body: ### Checklist
  
  - [X] I have searched the [existing issues](https://github.com/streamlit/streamlit/issues) for similar feature requests.
  - [X] I added a descriptive title and summary to this issue.
  
  ### Summary
  
  Browser sessions allow developers to track browser status in streamlit, so that they can implement features like authentication, persistent draft or shopping cart, which require the ability to keep user state after refreshing or reopen browsers.
  
  ### Why?
  
  The current streamlit session will lost state if users refresh or reopen their browser. And the effort of providing a API to write cookies has been pending for years. I think provide a dedicated API to track browser session would be cleaner and easier to implement.  
  With this API developers don't need to know how it works, it can be based on cookie or local storage or anything else. And developers can use it with singleton pattern to keep state for browser to persist whatever they want in streamlit.
  
  ### How?
  
  This feature will introduce several new APIs:
  * `st.get_browser_session(gdpr_consent=False)`, which will set a unique session id in browser if it doesn't exist, and return it.
  If `gdpr_consent` is set to True, a window will pop up to ask for user's consent before setting the session id.
  * `st.clean_browser_session()`, which will remove the session id from browser.
  
  The below is a POC of how `get_browser_session` can be used to implement a simple authentication solution:
  
  ```python
  from streamlit.web.server.websocket_headers import _get_websocket_headers
  from streamlit.components.v1 import html
  import streamlit as st
  
  from http.cookies import SimpleCookie
  from uuid import uuid4
  from time import sleep
  
  def get_cookie():
      try:
          headers = st.context.headers
      except AttributeError:
          headers = _get_websocket_headers()
      if headers is not None:
          cookie_str = headers.get("Cookie")
          if cookie_str:
              return SimpleCookie(cookie_str)
  
  
  def get_cookie_value(key):
      cookie = get_cookie()
      if cookie is not None:
          cookie_value = cookie.get(key)
          if cookie_value is not None:
              return cookie_value.value
      return None
  
  
  def get_browser_session():
      """
      use cookie to track browser session
      this id is unique to each browser session
      it won't change even if the page is refreshed or reopened
      """
      if 'st_session_id' not in st.session_state:
          session_id = get_cookie_value('ST_SESSION_ID')
          if session_id is None:
              session_id = uuid4().hex
              st.session_state['st_session_id'] = session_id
              html(f'<script>document.cookie = "ST_SESSION_ID={session_id}";</script>')
              sleep(0.1)  # FIXME: work around bug: Tried to use SessionInfo before it was initialized
              st.rerun()  # FIXME: rerun immediately so that html won't be shown in the final page
          st.session_state['st_session_id'] = session_id
      return st.session_state['st_session_id']
  
  
  @st.cache_resource
  def get_auth_state():
      """
      A singleton to store authentication state
      """
      return {}
  
  
  st.set_page_config(page_title='Browser Session Demo')
  session_id = get_browser_session()
  
  auth_state = get_auth_state()
  if session_id not in auth_state:
      auth_state[session_id] = False
  
  st.write(f'Your browser session ID: {session_id}')
  
  if not auth_state[session_id]:
      st.title('Input Password')
      token = st.text_input('Token', type='password')
      if st.button('Submit'):
          if token == 'passw0rd!':
              auth_state[session_id] = True
              st.rerun()
          else:
              st.error('Invalid token')
  else:
      st.success('Authentication success')
      if st.button('Logout'):
          auth_state[session_id] = False
          st.rerun()
      st.write('You are free to refresh or reopen this page without re-authentication')
  ```
  
  A more complicated example of using this method to work with oauth2 can be tried here: https://ai4ec.ikkem.com/apps/op-elyte-emulator/ 
  
  ### Additional Context
  
  Related issues:
  * https://github.com/streamlit/streamlit/issues/861
  * https://github.com/streamlit/streamlit/issues/8518