Manejo de sesión utilizando el cliente de Python Solicits -- python campo con python-3.x campo con http campo con web-scraping campo con session camp codereview Relacionados El problema

Session handling using Python Requests client


5
vote

problema

Español

Estoy usando este código para iniciar sesión en un sistema de inicio de sesión de experimentos creado por mí para este propósito.

  import requests import re  def get_page_data(regex, req):     match = re.compile(regex).search(req.text)     if match != None:         return match.group(1)     return 'no match found on {}'.format(regex)  def print_req_data(req, req_name):     print('{} status code: {}'.format(req_name, req.status_code))     print('{} title: {}'.format(req_name, get_page_data('<title>(.*?)</title>', req)))     print('{} content: {}'.format(req_name, req.text))  form_url = 'http://migueldvl.com/heya/login/' post_url = 'http://migueldvl.com/heya/login/process.php' headers = {'User-agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:7.0.1) Gecko/20100101 Firefox/7.0.1'}  with requests.Session() as s:     # get form page, so the cookies are set (form token)     logged_out_req = s.get(form_url, headers=headers)     print_req_data(logged_out_req, 'Logged out request')     title_logout = get_page_data('<title>(.*?)</title>', logged_out_req)     # getting the form token     token = get_page_data('<input type="hidden" name="token" value="(.*?)">', logged_out_req)     login_data = {'password' : 'password', 'username' : 'miguel', 'token': token}     # posting the data to the post url     post_req = s.post(post_url, data=login_data, headers=headers)     print_req_data(post_req, 'Post request (redirect page)')     check_post_title = get_page_data('<title>(.*?)</title>', post_req)     # comparing the titles (logged out title with redirect page title) so i see if login success     if(check_post_title != title_logout):         print('SUCCESS [+] Checking if still logged in...')         # going to see if i'm still loggin, see if our loggedin session is permanent         logged_req = s.get(form_url, headers=headers)         print_req_data(logged_req, 'Check if still logged request')         title_check = get_page_data('<title>(.*?)</title>', logged_req)         if(title_check == check_post_title):             print('You are still loogedin')         else:             print('Not loggeding anymore')     else:         print('FAIL LOGIN')         print_req_data(post_req, 'Post request (redirect page)')   

Me preguntaba si hay una mejor manera de hacer esto, especialmente con respecto a:

  1. ¿Hay una mejor manera de obtener el token de forma? Intenté revisar los encabezados,

      logged_out_page = s.get(form_url, headers=headers) print(logged_out_page.headers) # headers the server sent back to us print(logged_out_page.request.headers) # headers we sent to the server   

Sé que Sesión Los valores no se almacenan en nuestra máquina ( Navegador) A diferencia de las cookies normales, las se almacenan en el servidor, por lo que el valor real de la sesión no esté en los encabezados (solo una clave de identificación para el servidor, por lo que puede obtener los datos reales almacenados en él). Pero, ¿en todos modos, además, además de usar REGEX para extraer el valor de la sesión? PD: (Cookie de sesión producida con PHP, $_SESSION['token] = md5(time()) ).

  1. ¿Hay alguna manera (además de hacer una comparación de cadenas del título de la página o algún otro elemento en la página) para verificar si el inicio de sesión fue exitoso?

Cualquier otro comentario y sugerencias, por supuesto, bienvenido. Si desea probar este código (Python3, usando los enlaces anteriores, form_url3 y post_url4 ) con el nombre de usuario miguel y la contraseña < Código> password .

PS: Tenga en cuenta que este código se basa en el mecánico del sistema de registro que creé (el más habitual, supongo). No deseo ninguna mejoras en este código basado en otro

Original en ingles

I'm using this code to login to an experiment login system created by me for this purpose.

import requests import re  def get_page_data(regex, req):     match = re.compile(regex).search(req.text)     if match != None:         return match.group(1)     return 'no match found on {}'.format(regex)  def print_req_data(req, req_name):     print('{} status code: {}'.format(req_name, req.status_code))     print('{} title: {}'.format(req_name, get_page_data('<title>(.*?)</title>', req)))     print('{} content:\n{}'.format(req_name, req.text))  form_url = 'http://migueldvl.com/heya/login/' post_url = 'http://migueldvl.com/heya/login/process.php' headers = {'User-agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:7.0.1) Gecko/20100101 Firefox/7.0.1'}  with requests.Session() as s:     # get form page, so the cookies are set (form token)     logged_out_req = s.get(form_url, headers=headers)     print_req_data(logged_out_req, 'Logged out request')     title_logout = get_page_data('<title>(.*?)</title>', logged_out_req)     # getting the form token     token = get_page_data('<input type="hidden" name="token" value="(.*?)">', logged_out_req)     login_data = {'password' : 'password', 'username' : 'miguel', 'token': token}     # posting the data to the post url     post_req = s.post(post_url, data=login_data, headers=headers)     print_req_data(post_req, 'Post request (redirect page)')     check_post_title = get_page_data('<title>(.*?)</title>', post_req)     # comparing the titles (logged out title with redirect page title) so i see if login success     if(check_post_title != title_logout):         print('SUCCESS\n[+] Checking if still logged in...')         # going to see if i'm still loggin, see if our loggedin session is permanent         logged_req = s.get(form_url, headers=headers)         print_req_data(logged_req, 'Check if still logged request')         title_check = get_page_data('<title>(.*?)</title>', logged_req)         if(title_check == check_post_title):             print('You are still loogedin')         else:             print('Not loggeding anymore')     else:         print('FAIL LOGIN')         print_req_data(post_req, 'Post request (redirect page)') 

I was wondering if there is a better way to do this, especially with regard to:

  1. Is there a better way to get the form token? I tried checking the headers,

    logged_out_page = s.get(form_url, headers=headers) print(logged_out_page.headers) # headers the server sent back to us print(logged_out_page.request.headers) # headers we sent to the server 

I know that session values are not stored on our machine (browser) unlike normal cookies, those are stored in the server so the real session value is not on the headers (just some id key to the server, so it can fetch the real data stored on it). But is there anyway besides using regex to extract the session value? PS: (session cookie produced with php, $_SESSION['token] = md5(time())).

  1. Is there a way (besides doing a string comparison of the page title, or some other element on the page) to check if the login was successful?

Any other comments and suggestions are, of course, welcome. If you'd like to test this code (python3, using the links above, form_url and post_url) with the username miguel and the password password.

PS: Bear in mind that this code is based on the loggedin system mechanic that I created (the most usual, i guess). I don't wish any improvements on this code based on another

              
       
       

Lista de respuestas

4
 
vote
vote
La mejor respuesta
 

POR FAVOR, NO UTILICE REGEXES

Las expresiones regulares son herramientas eléctricas. Puedes usarlos para muchas situaciones, pero tienden a ser intrínsecamente frágiles. Son especialmente frágiles para analizar HTML, en parte debido a lo indulgente que serán la mayoría de los navegadores. Recomiendo usar un analizador dedicado para ello. Si decidió que, dado que esta es una página que controlas, no necesita ser tan cuidadoso, solo tenga en cuenta.

getSelection5

No debe ejecutar ningún código en el organismo principal de su programa, cualquier cosa que se ejecute debe estar dentro de un bloque 99887766655443316

getSelection7

No devuelva un valor si no se encontró nada; Esto sería muy inesperado (y sería molesto verificar, con unos pocos casos de borde). En su lugar, levante una excepción adecuada.

Tampoco necesita hacer getSelection8 , simplemente haga 99887766555443319

  Scanner0 

favorece los buenos nombres sobre los comentarios

Los comentarios son casi siempre un pecado. Un pecado necesario, pero significan que no has podido expresarte lo suficiente en el código. La mayoría de sus comentarios serían grandes nombres de funciones, por ejemplo.

  Scanner1  

se convierte en

  Scanner2  

También necesita desesperadamente WhiteSpace: agregue las nuevas líneas generales para agrupar las secciones de código. Esta es también una buena manera de ver dónde debe crear una nueva función.

He dejado fuera la impresión, porque ...

No imprime Willy Nilly

La mayoría de las veces, tiene un montón de declaraciones de impresión, están destinadas a ser una salida de depuración; Retire eso antes de que realmente use esto. Ocasionalmente, si necesita algún tipo de script de administración o necesita saber el estado que está bien, pero asegúrese de que está imprimiendo el mínimo de lo que necesita, y un archivo de registro aún va a ser mejor.

terminé con algo como esto. Muchas de las funciones terminan sin hacer un lote entero, y si no crees que están agregando una gran cantidad de valor, elimínelos, el punto de ellos, sin embargo, es dejarlo en claro qué se pretende hacer cada paso. . Notará que nunca hago ningún manejo de errores: no sé lo que realmente quiere hacer cuando falla el partido.

  Scanner3  

 

Please don't use regexes

Regular expressions are power tools. You can use them for many situations, but they tend to be inherently fragile. They're especially fragile for parsing HTML, in part because of how lenient most browsers will be. I'd recommend using a dedicated parser for it. If you decided that since this is a page you control you don't need to be that careful that's fine, just be aware.

main

You shouldn't execute any code in the main body of your program - anything that should execute should be inside of an if __name__ == '__main__': block, and that should still be broken up into functions for ease of use.

get_page_data

Don't return a value if nothing was found; this would be very unexpected (and it would be annoying to check for, with a few edge cases). Instead raise an appropriate exception.

You also don't need to do if match != None:, just do if match:

class NoMatchFoundException(Exception): pass  def get_page_data(regex, req):     match = re.compile(regex).search(req.text)     if match:         return match.group(1)     raise NoMatchFoundException("No match found on {}".format(regex)) 

Favor good names over comments

Comments are almost always a sin. A necessary sin, but they mean that you haven't been able to sufficiently express yourself in code. Most of your comments would be great function names, e.g.

# get form page, so the cookies are set (form token) logged_out_req = s.get(form_url, headers=headers) print_req_data(logged_out_req, 'Logged out request') title_logout = get_page_data('<title>(.*?)</title>', logged_out_req) 

becomes

def get_form_page(session, url, headers):     return session.get(url, headers=headers)  def get_page_title(page):     return get_page_data('<title>(.*?)</title>', page)  logged_out_req = get_form_page(s, form_url, headers) logout_page_title = get_page_title(logged_out_req) 

Also you desperately need whitespace - add newlines liberally to group like sections of code. This is also a good way to see where you should create a new function.

I've left out the printing, because...

Don't print willy nilly

Most of the time you have a bunch of print statements they are intended to be debugging output; remove that before you actually use this. Occasionally if you need some sort of admin script or you need to know the status that's fine, but make sure you're printing out the bare minimum of what you need, and a log file is still going to be better.

I ended up with something like this. A lot of the functions end up not doing a whole lot, and if you don't think they're adding a lot of value remove them - the point of them, however, is to make it clear what each step is intended to do. You'll note that I never do any error handling - I don't know what you actually want to be doing when the match fails.

import requests import re  class NoMatchFoundException(Exception): pass  def get_page_data(regex, req):     match = re.compile(regex).search(req.text)     if match:         return match.group(1)     raise NoMatchFoundException("No match found on {}".format(regex))  def get_page_title(page):     return get_page_data("<title>(.*?)</title>", page)  def get_page(session, url, headers, data=None):     data = data if data else {}     return session.get(url, headers=headers, data=data)  def print_req_data(req, req_name):     print('{} status code: {}'.format(req_name, req.status_code))     print('{} title: {}'.format(req_name, get_page_title(req)))     print('{} content:\n{}'.format(req_name, req.text))  def get_form_token(page):     return get_page_data('<input type="hidden" name="token" value="(.*?)">', page)  def logged_in(logout, logged):     return get_page_title(logout) != get_page_title(logged)  def same_page(first, second):     return get_page_title(first) == get_page_title(second)  def test_login(form_url, post_url, headers, username, password):     with requests.Session() as s:         logout_page = get_page(s, form_url, headers)          form_token = get_form_token(logout_page)         login_data = {'password' : password, 'username' : username 'token': form_token}          logged_in_page = get_page(s, post_url, headers, login_data)          if logged_in(logout_page, logged_in_page):             logged_in_test = get_page(s, form_url, headers)              if same_page(logged_in_test, logged_in_page):                 print('You are still logged-in')             else:                 print('Not logged-in anymore')         else:             print('FAIL LOGIN')             print_req_data(post_req, 'Post request (redirect page)')  if __name__ == '__main__':     form_url = 'http://migueldvl.com/heya/login/'     post_url = 'http://migueldvl.com/heya/login/process.php'     headers = {'User-agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:7.0.1) Gecko/20100101 Firefox/7.0.1'}     username = 'miguel'     password = 'password'      test_login(form_url, post_url, headers, username, password) 
 
 
       
       

Relacionados problema

4  Envoltura de sesión  ( Session wrapper ) 
Tengo dos tipos de envoltorios de sesión: tipo 1 public class SessionHandler { public static SessionHandler CurrentSession { get ...

9  Haciendo una clase de sesión simple más asegurada  ( Making a simple session class more secured ) 
Acabo de escribir la clase de sesión a continuación. Solicito humildemente una revisión sobre cómo hacer que esto sea aún más asegurado / cómo las sesiones no...

6  Sistema de inicio de sesión con sesión usando CodeIgniter  ( Login system with session using codeigniter ) 
Implementé un sistema de inicio de sesión, con sesión, utilizando CodeIgniter. Si la sesión no existe, redirige a la página de inicio de sesión. Por favor rev...

3  Seguimiento simple de usuarios en línea en ASP.NET  ( Simple tracking online users in asp net ) 
Escribí un seguimiento de usuarios simples en línea para mi proyecto ASP.NET MVC. en global.asax, agregué: protected void Session_Start(Object sender, ...

8  Manejo de forma segura una aplicación protegida con contraseña  ( Securely handling a password protected application ) 
Tengo algunas aplicaciones pequeñas que quiero asegurar. He estado usando la siguiente configuración que creo que es bastante segura, pero nunca he podido p...

2  Sesión nhibernate y implementación de transacciones  ( Nhibernate session and transaction implementation ) 
Para crear una arquitectura de acoplamiento suelto en mis aplicaciones web, he creado mi propia implementación para ORM, en este caso, NHibernate. Quiero qu...

9  Primer sistema de inicio de sesión PHP  ( First php login system ) 
¡Este es mi primer intento de un sistema de inicio de sesión! Solo he tenido aproximadamente 2 días de experiencia con MySQL y PHP hasta ahora y esto es lo qu...

1  Almacenar JWT en el lado del cliente y poner tokens en toda la solicitud futura  ( Storing jwt in client side and putting tokens in all the future request ) 
He comenzado a usar Nodejs con express JS y Passportjs y JWT para la autenticación del usuario. Soy capaz de autenticar al usuario y generar token JWT. Estoy ...

4  Formato de cheques contra una sesión  ( Formatting checks against a session ) 
Este es el código actual que se pone en un cuadro de opción, hay una manera de hacer que este código sea más eficiente y use menos código <select name="sea...

1  Guardar datos a una sesión  ( Saving data to a session ) 
Estoy un poco confundido Si ahorrar la información al código de sesión a continuación, pertenece a la acción del controlador como se muestra a continuación o ...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos