    def set_state_cookie(self, handler, next_url=None):
        """Generate an OAuth state and store it in a cookie

        Parameters
        ----------
        handler : RequestHandler
            A tornado RequestHandler
        next_url : str
            The page to redirect to on successful login

        Returns
        -------
        state : str
            The OAuth state that has been stored in the cookie (url safe, base64-encoded)
        """
        extra_state = {}
        if handler.get_cookie(self.state_cookie_name):
            # oauth state cookie is already set
            # use a randomized cookie suffix to avoid collisions
            # in case of concurrent logins
            app_log.warning("Detected unused OAuth state cookies")
            cookie_suffix = ''.join(
                random.choice(string.ascii_letters) for i in range(8)
            )
            cookie_name = f'{self.state_cookie_name}-{cookie_suffix}'
            extra_state['cookie_name'] = cookie_name
        else:
            cookie_name = self.state_cookie_name
        state_id = self.generate_state(next_url, **extra_state)
        kwargs = {
            'path': self.cookie_path,
            'httponly': True,
            # Expire oauth state cookie in ten minutes.
            # Usually this will be cleared by completed login
            # in less than a few seconds.
            # OAuth that doesn't complete shouldn't linger too long.
            'max_age': 600,
        }
        public_url = os.getenv("JUPYTERHUB_PUBLIC_URL")
        if public_url:
            if urlparse(public_url).scheme == 'https':
                kwargs['secure'] = True
        else:
            if get_browser_protocol(handler.request) == 'https':
                kwargs['secure'] = True

        # don't allow overriding some fields
        no_override_keys = set(kwargs.keys()) | {"expires_days", "expires"}

        # load user cookie overrides
        for key, value in self.cookie_options.items():
            # don't include overrides
            if key.lower() not in no_override_keys:
                kwargs[key] = value
        handler.set_secure_cookie(cookie_name, state_id, **kwargs)
        return state_id
Generate an OAuth state and store it in a cookie

Parameters
----------
handler : RequestHandler
A tornado RequestHandler
next_url : str
The page to redirect to on successful login

Returns
-------
state : str
The OAuth state that has been stored in the cookie (url safe, base64-encoded)
jupyterhub/services/auth.py