¿Cómo generar _forum_session y _t para un usuario a través de código/llamada API o sin iniciar sesión en el navegador?

He escrito un código para generar cookies (_forum_session y _t) a través de Selenium y Python. Pero en este caso, también debemos completar manualmente el número de teléfono y el OPT para validar. Quiero que la generación de cookies sea completamente automática a través de código, no quiero completar nada manualmente. ¿Cómo puedo lograr esto?

¿Puedes retroceder y describir qué problema resolverá tener esas cookies?

¿Qué intentas lograr? ¿Intentas que Discourse se autentique contra tu aplicación? ¿Quizás echa un vistazo a DiscourseConnect - Inicio de sesión único oficial para Discourse (sso)?

A través de generate_cookies.py, recibí cookies.pkl que utilizo para probar el inicio de sesión automático cada 5 minutos.

Así que tengo un archivo login_12.py que llamo cada 5 minutos para probar mis inicios de sesión
login_12.py (a continuación se muestra un ejemplo de código)

import cookies.pkl
driver.get("https://forum.discourse.org/")
    WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
    logger.debug(jlog.format(timestamp=datetime.now(), level="DEBUG", status="Executing", message="Homepage reloaded"))
    time.sleep(3)

    cookies = pickle.load(open("cookies.pkl", "rb"))
    for cookie in cookies:
        print(cookie)
        driver.add_cookie(cookie)
    logger.debug(jlog.format(timestamp=datetime.now(), level="DEBUG", status="Executing", message="Added cookies"))
    time.sleep(2)

    driver.get(driver.current_url)
        logger.debug(jlog.format(timestamp=datetime.now(), level="DEBUG", status="Executing", message="Homepage reloaded"))

Quiero generar cookies automáticamente sin usar un navegador. así que todo el proceso será automático.

Todavía estás describiendo tu solución propuesta en lugar del problema que intentas resolver.

¿Por qué necesitas las cookies si no necesitas un navegador?

¿Estás intentando que tu aplicación externa pueda hacer algo en Discourse? ¿Quizás simplemente usar una clave API?

1 me gusta

¿Por qué necesitas las cookies?
Respuesta: porque sin agregar el archivo cookies.pkl no podemos iniciar sesión a través del archivo login_12.py.

Por ahora, para generar cookies, debemos completar el número de teléfono y la OTP manualmente en el navegador Chrome Driver. No quiero completar nada manualmente, por eso no quiero usar el navegador para generar cookies.

generate_cookies.py (código de ejemplo)

    from selenium import webdriver
    import undetected_chromedriver as uc
    
    options = uc.ChromeOptions()
    #options.add_argument('--headless')
    options.add_argument("--disable-extensions")
    options.add_argument("--disable-popup-blocking")

    # iniciar sesión
    GMAIL = 'discourse.mytest@ymail.com'
    PASSWORD = 'test1234'

    driver.get("https://forun.discourse.org/")
    print(driver.title)
    WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
    print('Página de inicio cargada')


    WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.CLASS_NAME, 'login-button')))
    login = driver.find_elements_by_class_name("login-button")[0]
    print(login)
    login.send_keys(Keys.RETURN)
    print(driver.current_url)
    driver.get(driver.current_url)
    print("correo electrónico")
    WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
    print('Página de correo electrónico cargada')
    #print(driver.page_source)

    driver.find_element_by_xpath("/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div/div[1]/div/div[1]/input").send_keys(GMAIL)
    driver.find_element_by_xpath("/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div/div[1]/div/div[1]/input").send_keys(Keys.RETURN)
    print("Correo electrónico introducido")

    time.sleep(3)

    WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
    print('Página de contraseña cargada')
    #print(driver.page_source)

    driver.find_element_by_xpath("/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div[1]/div/div/div/div/div[1]/div/div[1]/input").send_keys(PASSWORD)
    driver.find_element_by_xpath("/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div[1]/div/div/div/div/div[1]/div/div[1]/input").send_keys(Keys.RETURN)
    print("Contraseña introducida")
    time.sleep(3)

    WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
    print('Inicio de sesión completado')
    print(driver.title)

    #print(driver.find_element_by_xpath("/html/body").get_attribute('innerHTML'))

    if not "Discourse Forum" in driver.title:
        raise Exception('Error de inicio de sesión')
    else:
        print("Página de inicio cargada")
    driver.get(driver.current_url+'/c/announcements/5')
    WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/head/title')))
    print('Intentando acceder a la página de anuncios')
    print(driver.title)

Finalmente quiero lograr esto.

if (obtener la fecha de caducidad del navegador headless desde el almacenamiento local >= ahora)
{
#ejecutar generate cookies (problema con esta parte para que sea automática, actualmente algunas partes son manuales)
#cargar el archivo cookies.pkl en el directorio apropiado
}else{
#ejecutar login_12.py para iniciar sesión
}

#acceder al almacenamiento local para el navegador chrome headless
#agregar/actualizar la fecha de caducidad en la variable de almacenamiento local

¿Cómo y por qué?
¿Puede rellenar el número de teléfono (dónde se solicita?) automáticamente y desactivar el OTP para ese usuario?

1 me gusta

@RGJ ¿Hay algún endpoint o API disponible que podamos llamar para obtener un token de acceso de inicio de sesión válido?

Si lo que intentas hacer es permitir que las personas inicien sesión en Discourse usando tu otra aplicación, o que inicien sesión en tu otra aplicación usando Discourse, entonces quieres implementar DiscourseConnect, al que enlacé arriba. Puedes consultar esa página para ver la documentación y los ejemplos de código.

Todavía no me queda claro qué es lo que intentas conseguir.

Si necesitas integrar otra página web usando la autenticación de Discourse como fuente de verdad, puedes usar Discourse como proveedor de SSO.

Si necesitas hacer llamadas de servidor a servidor a la API de Discourse, puedes crear claves de API en /admin/api/keys.

¿Puedes compartir cuál es la necesidad funcional que intentas abordar?

2 Me gusta

Tenemos el archivo login_12.py que prueba la funcionalidad de inicio de sesión de Discourse cada 5 minutos.

Tuvimos que agregar cookies (cookies.pkl) en login_12.py para iniciar sesión correctamente.

¿Cómo obtuvimos las cookies (cookies.pkl)?
Tenemos otro archivo, generate_cookies.py, en este archivo tenemos el correo electrónico y la contraseña del usuario codificados, usando esto generamos cookies para ese usuario en particular y escribimos un archivo cookies.pkl.

Para generar cookies usamos un navegador, lo cual queremos evitar y este paso queremos hacerlo automáticamente a través de código sin usar un navegador.

Contenido de generate_cookies.py

from selenium import webdriver
import undetected_chromedriver as uc
from selenium.webdriver.common.keys import Keys
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import pickle


options = uc.ChromeOptions()
#options.add_argument('--headless')
options.add_argument("--disable-extensions")
options.add_argument("--disable-popup-blocking")
options.add_argument("--profile-directory=Default")
options.add_argument("--ignore-certificate-errors")
options.add_argument("--disable-plugins-discovery")
options.add_argument("--incognito")
options.add_argument("user_agent=DN")


if __name__ == "__main__":    #Necesario solo para Windows (Error en undetected_chromedriver)
    driver = uc.Chrome(options=options)

    # iniciar sesión
    GMAIL = 'discourse.testing@gmail.com'
    PASSWORD = 'discoursetest123'

    driver.get("https://forum.discourse.org/")
    print(driver.title)
    WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
    print('Página de inicio cargada')


    WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.CLASS_NAME, 'login-button')))
    login = driver.find_elements_by_class_name("login-button")[0]
    print(login)
    login.send_keys(Keys.RETURN)
    print(driver.current_url)
    driver.get(driver.current_url)
    print("email")
    WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
    print('Página de correo electrónico cargada')
    #print(driver.page_source)

    driver.find_element_by_xpath("/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div/div[1]/div/div[1]/input").send_keys(GMAIL)
    driver.find_element_by_xpath("/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div/div[1]/div/div[1]/input").send_keys(Keys.RETURN)
    print("Correo electrónico introducido")

    time.sleep(3)

    WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
    print('Página de contraseña cargada')
    #print(driver.page_source)

    driver.find_element_by_xpath("/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div[1]/div/div/div/div/div[1]/div/div[1]/input").send_keys(PASSWORD)
    driver.find_element_by_xpath("/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div[1]/div/div/div/div/div[1]/div/div[1]/input").send_keys(Keys.RETURN)
    print("Contraseña introducida")
    time.sleep(3)

    WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
    print('Inicio de sesión completado')
    print(driver.title)

    #print(driver.find_element_by_xpath("/html/body").get_attribute('innerHTML'))

    if not "Discourse Forum" in driver.title:
        raise Exception('Error de inicio de sesión')
    else:
        print("Página de inicio cargada")
    driver.get(driver.current_url+'/c/announcements/5')
    WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/head/title')))
    print('Intentando página de anuncios')
    print(driver.title)
    if not "Latest Announcements topics - Discourse Forum" in driver.title:
        raise Exception('Función de error de inicio de sesión')
    print("¡Éxito!")

    pickle.dump( driver.get_cookies() , open("cookies2.pkl","wb"))

Esto es más una pregunta de Python.

Puede usar la biblioteca Requests en Python para realizar sus solicitudes. Admite cookies de varias maneras, aquí hay algunos ejemplos. Le recomendaría que utilizara un objeto Session.

Si desea analizar la salida HTML, puede usar BeautifulSoup.

1 me gusta

Entonces, ¿lo que intentas lograr es probar continuamente que los inicios de sesión funcionen? ¿No intentas hacer nada? ¿Solo quieres asegurarte de que si alguien intenta iniciar sesión en tu sitio, funcionará (probablemente)?