2013-09-03 9 views
9

Sto tentando di accedere a un sito Web e di reindirizzare a una pagina protetta da un'azione di un binario. Il mio codice è simile a questo.Archivia cookie di sessione di login nel browser utilizzando ruby ​​mechanize

def redirect_to_external 
    agent = Mechanize.new 
    page = agent.get('http://example.com/home.asp') 
    login_form = page.form_with(:name => "loginForm") 
    login_form.login = 'username' 
    login_form.password = 'password' 
    agent.submit(login_form) 

    #cookies = agent.cookie_jar.store.map {|i| i} #need to store the cookie with a specific in browser 
    redirect_to('http://example.com/admin.asp') #page behind password protection 
end 

accesso riesce in background, ma vero e proprio reindirizzamento alla pagina di amministrazione sta chiedendo ancora una volta per l'autenticazione nel browser, come il cookie di sessione non viene memorizzato nel browser. Ho provato a memorizzare i cookie da cookie_jar, ma non ho trovato il modo esatto per farlo. Qualcuno mi può aiutare in questo?

+0

Rendi agent un'istanza var o passala a redirect_to. Ha il cookie, non è necessario memorizzarlo. – pguardiario

+0

Grazie. Ma rendendo @agent = Mechanize.new non ha funzionato. Inoltre, redirect_to non accetta l'agente come parametro. È possibile mostrare un esempio per questo per favore? – Vijendra

+0

Non so come aiutarti senza essere accondiscendente. Pensa solo al motivo per cui non dovresti istanziare l'oggetto Mechanize come una variabile locale del tuo metodo (suggerimento - non resterà a lungo.) – pguardiario

risposta

1

prega di fare riferimento a seguito code.This creano un codice all'interno di un blocco di questo manterrà l'autenticazione,

def redirect_to_external 
    @agent = Mechanize.new 
    @agent.get('http://example.com/home.asp') do | home_page | 
    login_form = home_page.form_with(:name => "loginForm") 
    login_form.login = 'username' 
    login_form.password = 'password' 
    @agent.submit(login_form) 
    #cookies = agent.cookie_jar.store.map {|i| i} #need to store the cookie with a specific in browser 
    @agent.get('http://example.com/admin.asp') #page behind password protection 
    end 
end 
6

Ho lottato con questo per molto tempo! Le altre risposte su StackOverflow non hanno risolto esattamente come memorizzare nella cache i cookie e recuperarli, quindi sto combinando la mia esperienza con le altre risposte che ho letto, in una soluzione qui.

(Vedi:

Rails 3 - Log into another site and keep cookie in session

Store login session cookie in browser using ruby mechanize

Get Mechanize to handle cookies from an arbitrary POST (to log into a website programmatically)

keep mechanize page over request boundaries

).

Ho usato questa soluzione per creare un OAuth2.0 personalizzato per un sito Web che non supporta OAuth2.0 reale.

  1. L'utente mi ha fornito le credenziali per l'altro sito. Li ho passati sul sito tramite Mechanize nel metodo di creazione del mio controller Sessions e li ho immediatamente distrutti (non voglio toccare il più possibile le cose sicure di qualcun altro. Questo è il motivo per cui tutto questo avviene anche in un SSL).

  2. Ciò significa che la mia istanza di Mechanize con i cookie necessari verrà distrutta quando reindirizzerò da un'altra parte nella mia app. Ad esempio, nella mia app, ho successivamente reindirizzato al metodo index del mio Sessions Controller. Se sei nuovo alle rotaie potresti pensare che le stesse variabili di istanza (come l'agente di meccanizzazione con quei cookie) sarebbero disponibili da create a index, ma è sbagliato, ogni reindirizzamento distruggerà tutto! (in pratica)

  3. Quindi, prima del reindirizzamento, è necessario memorizzare i cookie. L'unico modo per archiviare qualcosa di simile tra le richieste è tramite la cache, e alla cache non piace memorizzare l'intera istanza di mechanize. Invece è necessario memorizzare i cookie serializzati. L'unico problema è che Mechanize non ha un metodo per esportare i suoi cookie come una stringa, può solo salvarli come file. Cosa fare?

  4. StringIO al soccorso! Puoi essenzialmente simulare un file con StringIO. Dopo tutto quello che parlare, ecco il codice:

    @agent = Mechanize.new 
    #handle the sign in stuff 
    stringio = StringIO.new 
    @agent.cookie_jar.save(stringio, session: true) 
    cookies = stringio.string 
    session[:login_cookies] = cookies 
    

Si noti che ho passato session: true al metodo save di cookie_jar. Senza questo parametro, il cookie salverà solo i cookie non di sessione.

  1. Così ora la nostra cache di sessione ha una stringa che contiene tutti i cookie da mechanize. Per farli tornare dopo un reindirizzamento avrete bisogno di nuovo StringIO:

    @agent = Mechanize.new 
    cookies = session[:login_cookies] 
    @agent.cookie_jar.load StringIO.new(cookies) 
    
  2. E voilà! Il tuo nuovo agente è pronto ad agire proprio come il vecchio.

+0

Stava cercando come fare esattamente la stessa cosa con Mechanize (salva i cookie e caricali senza dover salvare e caricare i file reali). Grazie mille! – uechan

+0

Un post luminoso! Grazie! – flunder

+0

Grande risposta, ho una domanda: ho solo una familiarità immediata con Ruby, quindi non sono sicuro di cosa significhi la sintassi sulla linea 'session [: login_cookies] = cookies'. Attualmente riceve un errore perché non sa quale sia la variabile 'session'. Grazie! –

Problemi correlati