C# client HttpWebRequest on a rails application and reuse a session - ruby-on-rails-3
I have a rails 3 application running on windows and apache server.
As I have to use NTLM I use the sspi auth module of apache.
As the auth module don't work well with IE (each request results in 401 and another request) we setup the rails application that we only use the authentication on one url /login inside apache.
The rails application has a before_filter :authenticate.
If we don't have a valid login we redirect (http 302) to the login controller, authenticate and redirect back to the original url (request.env['REQUEST_URI]).
On a normal browser login it works perfect. The web browser login any url, gets redirected to authenticate and redirect back to the target url.
Now I have a client plugin writte as a C# project. There I have to make some web request calls to retrieve some json data.
If I make a simple GET request I manage the client to work:
CookieContainer cookies = new CookieContainer();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = WebRequestMethods.Http.Post;
request.AllowAutoRedirect = true;
request.CookieContainer = cookies;
if (isWindowAuthentication)
request.Credentials = CredentialCache.DefaultNetworkCredentials;
Which results in apache access.log like this:
192.168.14.9 - - [02/Jun/2012:11:26:15 +0200] "POST /ror/ioi/start HTTP/1.1" 302 123
192.168.14.9 - - [02/Jun/2012:11:26:16 +0200] "GET /ror/login?ror_referer=%2Fror%2Fioi%2Fstart HTTP/1.1" 401 401
192.168.14.9 - - [02/Jun/2012:11:26:16 +0200] "GET /ror/login?ror_referer=%2Fror%2Fioi%2Fstart HTTP/1.1" 401 401
192.168.14.9 - rausch [02/Jun/2012:11:26:16 +0200] "GET /ror/login?ror_referer=%2Fror%2Fioi%2Fstart HTTP/1.1" 302 94
But the redirect won't work if I have to post data (like upload a document which I want to do).
So my approach was to make a request, store the session information and send them with the POST.
CookieContainer cookieContainer = new CookieContainer();
WebHeaderCollection headerCollection = new WebHeaderCollection();
if (Common.WindowAuthentication)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Common.PortalUrl + Common.IoiStart);
request.Method = WebRequestMethods.Http.Post;
request.AllowAutoRedirect = true;
request.CookieContainer = cookieContainer;
request.Credentials = CredentialCache.DefaultNetworkCredentials;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
for (int i = 0; i < response.Headers.Count; i++)
{
headerCollection.Add(response.Headers.AllKeys[i], response.Headers.Get(i));
}
response.Close();
}
LogWriter.LogError("second request");
string boundary = "----------------------------" +
DateTime.Now.Ticks.ToString("x");
HttpWebRequest httpWebRequest2 = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest2.ContentType = "multipart/form-data; boundary=" + boundary;
httpWebRequest2.Method = "POST";
httpWebRequest2.KeepAlive = true;
httpWebRequest2.AllowAutoRedirect = false;
httpWebRequest2.CookieContainer = cookieContainer;
for (int i = 0; i < headerCollection.Count; i++)
{
string key = headerCollection.GetKey(i);
if (key == "Set-Cookie")
{
key = "Cookie";
}
else
{
continue;
}
string value = headerCollection.Get(i);
httpWebRequest2.Headers.Add(key, value);
}
httpWebRequest2.ServicePoint.Expect100Continue = false;
httpWebRequest2.Accept = "*/*";
This ends in this (access.log):
192.168.14.9 - - [02/Jun/2012:11:51:22 +0200] "POST /ror/ioi/start HTTP/1.1" 302 123
192.168.14.9 - - [02/Jun/2012:11:51:22 +0200] "GET /ror/login?ror_referer=%2Fror%2Fioi%2Fstart HTTP/1.1" 401 401
192.168.14.9 - - [02/Jun/2012:11:51:22 +0200] "GET /ror/login?ror_referer=%2Fror%2Fioi%2Fstart HTTP/1.1" 401 401
192.168.14.9 - rausch [02/Jun/2012:11:51:22 +0200] "GET /ror/login?ror_referer=%2Fror%2Fioi%2Fstart HTTP/1.1" 302 94
192.168.14.9 - - [02/Jun/2012:11:51:22 +0200] "GET /ror/ioi/start HTTP/1.1" 200 27
192.168.14.9 - - [02/Jun/2012:11:51:22 +0200] "POST /ror/ioi/upload HTTP/1.1" 302 124
For the /ioi/upload request I disallow redirection.
Inspecting the rails settings (some code in application controller) I get this:
request: /ror/ioi/start
#<ActionDispatch::Request:0x4114458 #env={"SERVER_SOFTWARE"=>"thin 1.2.11 codename Bat-Shit Crazy", "SERVER_NAME"=>"thorx64", "rack.input"=>#<StringIO:0x41eaeb0>, "rack.version"=>[1, 0], "rack.errors"=>#<IO:<STDERR>>, "rack.multithread"=>false, "rack.multiprocess"=>false, "rack.run_once"=>false, "REQUEST_METHOD"=>"POST", "REQUEST_PATH"=>"/ror/ioi/start", "PATH_INFO"=>"/ioi/start", "REQUEST_URI"=>"/ror/ioi/start", "HTTP_VERSION"=>"HTTP/1.1", "HTTP_HOST"=>"thorx64", "HTTP_MAX_FORWARDS"=>"10", "HTTP_X_FORWARDED_FOR"=>"192.168.14.9", "HTTP_X_FORWARDED_HOST"=>"thorx64", "HTTP_X_FORWARDED_SERVER"=>"thorx64", "HTTP_CONNECTION"=>"Keep-Alive", "GATEWAY_INTERFACE"=>"CGI/1.2", "SERVER_PORT"=>"80", "QUERY_STRING"=>"", "SERVER_PROTOCOL"=>"HTTP/1.1", "rack.url_scheme"=>"http", "SCRIPT_NAME"=>"/ror", "REMOTE_ADDR"=>"127.0.0.1", "async.callback"=>#<Method: Thin::Connection#post_process>, "async.close"=>#<EventMachine::DefaultDeferrable:0x41ea700>, "action_dispatch.parameter_filter"=>[:password], "action_dispatch.secret_token"=>"a1ef5e037607d12742a40a0793de973a5e68605ccf087ad1baedaee6d811687b82a0671b94da2c4a9af2b481a5346585649e83d2f56f2838a4aca8eedbfc93b7", "action_dispatch.show_exceptions"=>true, "action_dispatch.remote_ip"=>127.0.0.1, "rack.session"=>{}, "rack.session.options"=>{:path=>"/", :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true, :id=>nil}, "rack.request.form_input"=>#<StringIO:0x41eaeb0>, "rack.request.form_hash"=>{}, "rack.request.form_vars"=>"", "action_dispatch.request.path_parameters"=>{:controller=>"ioi", :action=>"start"}, "action_controller.instance"=>#<IoiController:0x4114548 #action_has_layout=true, #view_context_class=nil, #_headers={"Content-Type"=>"text/html"}, #_status=200, #_response=#<ActionDispatch::Response:0x4114440 #writer=#<Proc:0x41143b0#D:/Informer/ruby/lib/ruby/gems/1.9.1/gems/actionpack-3.0.10/lib/action_dispatch/http/response.rb:43 (lambda)>, #block=nil, #length=0, #header={}, #status=200, #body=[], #cookie=[], #sending_file=false, #blank=false, #cache_control={}, #etag=nil, #request=#<ActionDispatch::Request:0x4114458 ...>>, #_request=#<ActionDispatch::Request:0x4114458 ...>, #_env={...}, #lookup_context=#<ActionView::LookupContext:0x4113390 #details_key=nil, #details={:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml], :formats=>[:html, :text, :js, :css, :ics, :csv, :xml, :rss, :atom, :yaml, :multipart_form, :url_encoded_form, :json, :flv, :file, :image, :auto, :sourcefile, :sourceimage, :sourceauto, :legacy, :edit], :locale=>[:de, :de]}, #skip_default_locale=false, #frozen_formats=false, #view_paths=[d:/Informer/company/latest/ror/app/views, d:/Informer/company/latest/ror/vendor/plugins/will_paginate/app/views, d:/Informer/company/latest/ror/vendor/plugins/usesguid/app/views, d:/Informer/company/latest/ror/vendor/plugins/acts_as_tree/app/views, d:/Informer/company/latest/ror/vendor/plugins/acts_as_solr/app/views]>, #_action_name="start", #_response_body=nil, #_config={}, #_params={"controller"=>"ioi", "action"=>"start"}>, "action_dispatch.request.request_parameters"=>{}, "rack.request.query_string"=>"", "rack.request.query_hash"=>{}, "action_dispatch.request.query_parameters"=>{}, "action_dispatch.request.parameters"=>{"controller"=>"ioi", "action"=>"start"}, "action_dispatch.request.formats"=>[text/html], "rack.session.record"=>#<ActiveRecord::SessionStore::Session id: nil, session_id: "c068a38edeb9bfa71aa5bf7885af35cd", client_ip: nil, username: nil, data: nil, created_at: nil, updated_at: nil>, "action_dispatch.request.flash_hash"=>nil}, #request_method="POST", #filtered_parameters={"controller"=>"ioi", "action"=>"start"}, #method="POST", #fullpath="/ror/ioi/start">
HTTP_VERSION => HTTP/1.1
HTTP_HOST => thorx64
HTTP_MAX_FORWARDS => 10
HTTP_X_FORWARDED_FOR => 192.168.14.9
HTTP_X_FORWARDED_HOST => thorx64
HTTP_X_FORWARDED_SERVER => thorx64
HTTP_CONNECTION => Keep-Alive
i am a user?: false
session:
request: /ror/login?ror_referer=%2Fror%2Fioi%2Fstart
request: /ror/ioi/start
#<ActionDispatch::Request:0x41eda00 #env={"SERVER_SOFTWARE"=>"thin 1.2.11 codename Bat-Shit Crazy", "SERVER_NAME"=>"thorx64", "rack.input"=>#<StringIO:0x3e6f4a8>, "rack.version"=>[1, 0], "rack.errors"=>#<IO:<STDERR>>, "rack.multithread"=>false, "rack.multiprocess"=>false, "rack.run_once"=>false, "REQUEST_METHOD"=>"GET", "REQUEST_PATH"=>"/ror/ioi/start", "PATH_INFO"=>"/ioi/start", "REQUEST_URI"=>"/ror/ioi/start", "HTTP_VERSION"=>"HTTP/1.1", "HTTP_HOST"=>"thorx64", "HTTP_COOKIE"=>"_ror_session=bfd6cdcd0650812edeb58c9a915e3948; user=rausch", "HTTP_MAX_FORWARDS"=>"10", "HTTP_X_FORWARDED_FOR"=>"192.168.14.9", "HTTP_X_FORWARDED_HOST"=>"thorx64", "HTTP_X_FORWARDED_SERVER"=>"thorx64", "HTTP_CONNECTION"=>"Keep-Alive", "GATEWAY_INTERFACE"=>"CGI/1.2", "SERVER_PORT"=>"80", "QUERY_STRING"=>"", "SERVER_PROTOCOL"=>"HTTP/1.1", "rack.url_scheme"=>"http", "SCRIPT_NAME"=>"/ror", "REMOTE_ADDR"=>"127.0.0.1", "async.callback"=>#<Method: Thin::Connection#post_process>, "async.close"=>#<EventMachine::DefaultDeferrable:0x3e6e668>, "action_dispatch.parameter_filter"=>[:password], "action_dispatch.secret_token"=>"a1ef5e037607d12742a40a0793de973a5e68605ccf087ad1baedaee6d811687b82a0671b94da2c4a9af2b481a5346585649e83d2f56f2838a4aca8eedbfc93b7", "action_dispatch.show_exceptions"=>true, "action_dispatch.remote_ip"=>127.0.0.1, "rack.session"=>{"current_user_id"=>49}, "rack.session.options"=>{:path=>"/", :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true, :id=>"bfd6cdcd0650812edeb58c9a915e3948"}, "rack.request.cookie_string"=>"_ror_session=bfd6cdcd0650812edeb58c9a915e3948; user=rausch", "rack.request.cookie_hash"=>{"_ror_session"=>"bfd6cdcd0650812edeb58c9a915e3948", "user"=>"rausch"}, "rack.session.record"=>#<ActiveRecord::SessionStore::Session id: 712, session_id: "bfd6cdcd0650812edeb58c9a915e3948", client_ip: "192.168.14.9", username: "rausch", data: "BAh7BkkiFGN1cnJlbnRfdXNlcl9pZAY6BkVGaTY=\n", created_at: "2012-06-02 11:51:22", updated_at: "2012-06-02 11:51:22">, "action_dispatch.request.path_parameters"=>{:controller=>"ioi", :action=>"start"}, "action_controller.instance"=>#<IoiController:0x41edac0 #action_has_layout=true, #view_context_class=nil, #_headers={"Content-Type"=>"text/html"}, #_status=200, #_response=#<ActionDispatch::Response:0x41ed9e8 #writer=#<Proc:0x41ed8e0#D:/Informer/ruby/lib/ruby/gems/1.9.1/gems/actionpack-3.0.10/lib/action_dispatch/http/response.rb:43 (lambda)>, #block=nil, #length=0, #header={}, #status=200, #body=[], #cookie=[], #sending_file=false, #blank=false, #cache_control={}, #etag=nil, #request=#<ActionDispatch::Request:0x41eda00 ...>>, #_request=#<ActionDispatch::Request:0x41eda00 ...>, #_env={...}, #lookup_context=#<ActionView::LookupContext:0x41ecc80 #details_key=nil, #details={:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml], :formats=>[:html, :text, :js, :css, :ics, :csv, :xml, :rss, :atom, :yaml, :multipart_form, :url_encoded_form, :json, :flv, :file, :image, :auto, :sourcefile, :sourceimage, :sourceauto, :legacy, :edit], :locale=>[:de, :de]}, #skip_default_locale=false, #frozen_formats=false, #view_paths=[d:/Informer/company/latest/ror/app/views, d:/Informer/company/latest/ror/vendor/plugins/will_paginate/app/views, d:/Informer/company/latest/ror/vendor/plugins/usesguid/app/views, d:/Informer/company/latest/ror/vendor/plugins/acts_as_tree/app/views, d:/Informer/company/latest/ror/vendor/plugins/acts_as_solr/app/views]>, #_action_name="start", #_response_body=nil, #_config={}, #_params={"controller"=>"ioi", "action"=>"start"}>, "action_dispatch.request.content_type"=>nil, "action_dispatch.request.request_parameters"=>{}, "rack.request.query_string"=>"", "rack.request.query_hash"=>{}, "action_dispatch.request.query_parameters"=>{}, "action_dispatch.request.parameters"=>{"controller"=>"ioi", "action"=>"start"}, "action_dispatch.request.formats"=>[text/html]}, #request_method="GET", #filtered_parameters={"controller"=>"ioi", "action"=>"start"}, #method="GET", #fullpath="/ror/ioi/start">
HTTP_VERSION => HTTP/1.1
HTTP_HOST => thorx64
HTTP_COOKIE => _ror_session=bfd6cdcd0650812edeb58c9a915e3948; user=rausch
HTTP_MAX_FORWARDS => 10
HTTP_X_FORWARDED_FOR => 192.168.14.9
HTTP_X_FORWARDED_HOST => thorx64
HTTP_X_FORWARDED_SERVER => thorx64
HTTP_CONNECTION => Keep-Alive
i am a user?: true
session: bfd6cdcd0650812edeb58c9a915e3948
request: /ror/ioi/upload
#<ActionDispatch::Request:0x4235610 #env={"SERVER_SOFTWARE"=>"thin 1.2.11 codename Bat-Shit Crazy", "SERVER_NAME"=>"thorx64", "rack.input"=>#<StringIO:0x3b754f0>, "rack.version"=>[1, 0], "rack.errors"=>#<IO:<STDERR>>, "rack.multithread"=>false, "rack.multiprocess"=>false, "rack.run_once"=>false, "REQUEST_METHOD"=>"POST", "REQUEST_PATH"=>"/ror/ioi/upload", "PATH_INFO"=>"/ioi/upload", "REQUEST_URI"=>"/ror/ioi/upload", "HTTP_VERSION"=>"HTTP/1.1", "HTTP_HOST"=>"thorx64", "HTTP_ACCEPT"=>"*/*", "HTTP_COOKIE"=>"_ror_session=bfd6cdcd0650812edeb58c9a915e3948; user=rausch", "HTTP_MAX_FORWARDS"=>"10", "HTTP_X_FORWARDED_FOR"=>"192.168.14.9", "HTTP_X_FORWARDED_HOST"=>"thorx64", "HTTP_X_FORWARDED_SERVER"=>"thorx64", "HTTP_CONNECTION"=>"Keep-Alive", "CONTENT_LENGTH"=>"100058", "CONTENT_TYPE"=>"multipart/form-data; boundary=----------------------------8cf0ecd4ab52a04", "GATEWAY_INTERFACE"=>"CGI/1.2", "SERVER_PORT"=>"80", "QUERY_STRING"=>"", "SERVER_PROTOCOL"=>"HTTP/1.1", "rack.url_scheme"=>"http", "SCRIPT_NAME"=>"/ror", "REMOTE_ADDR"=>"127.0.0.1", "async.callback"=>#<Method: Thin::Connection#post_process>, "async.close"=>#<EventMachine::DefaultDeferrable:0x3b749f8>, "action_dispatch.parameter_filter"=>[:password], "action_dispatch.secret_token"=>"a1ef5e037607d12742a40a0793de973a5e68605ccf087ad1baedaee6d811687b82a0671b94da2c4a9af2b481a5346585649e83d2f56f2838a4aca8eedbfc93b7", "action_dispatch.show_exceptions"=>true, "action_dispatch.remote_ip"=>127.0.0.1, "rack.session"=>{}, "rack.session.options"=>{:path=>"/", :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true, :id=>nil}, "rack.request.cookie_string"=>"_ror_session=bfd6cdcd0650812edeb58c9a915e3948; user=rausch", "rack.request.cookie_hash"=>{"_ror_session"=>"bfd6cdcd0650812edeb58c9a915e3948", "user"=>"rausch"}, "rack.session.record"=>#<ActiveRecord::SessionStore::Session id: 712, session_id: "bfd6cdcd0650812edeb58c9a915e3948", client_ip: "192.168.14.9", username: "rausch", data: "BAh7BkkiFGN1cnJlbnRfdXNlcl9pZAY6BkVGaTY=\n", created_at: "2012-06-02 11:51:22", updated_at: "2012-06-02 11:51:22">, "action_dispatch.request.content_type"=>multipart/form-data, "rack.request.form_input"=>#<StringIO:0x3b754f0>, "rack.request.form_hash"=>{"document"=>{"id"=>"20", "guid"=>"{ed20ec73-94bc-413b-b3a9-07b44ab6e624}"}, "file"=>{"name"=>"Dokument1.docx", "source"=>{:filename=>"Dokument1_201262114815.docx", :type=>"application/octet-stream", :name=>"file[source]", :tempfile=>#<File:C:/Windows/Temp/RackMultipart20120602-10036-1bfrx5x>, :head=>"Content-Disposition: form-data; name=\"file[source]\"; filename=\"C:\\Users\\rausch\\AppData\\Roaming\\TQsoft\\InformerOfficeExtension\\Temp\\Dokument1_201262114815.docx\"\r\n Content-Type: application/octet-stream\r\n"}, "pdf"=>{:filename=>"Dokument1_201262114815.pdf", :type=>"application/octet-stream", :name=>"file[pdf]", :tempfile=>#<File:C:/Windows/Temp/RackMultipart20120602-10036-1uzoxvw>, :head=>"Content-Disposition: form-data; name=\"file[pdf]\"; filename=\"C:\\Users\\rausch\\AppData\\Roaming\\TQsoft\\InformerOfficeExtension\\Temp\\Dokument1_201262114815.pdf\"\r\n Content-Type: application/octet-stream\r\n"}}}, "action_dispatch.request.path_parameters"=>{:controller=>"ioi", :action=>"upload"}, "action_controller.instance"=>#<IoiController:0x4235748 #action_has_layout=true, #view_context_class=nil, #_headers={"Content-Type"=>"text/html"}, #_status=200, #_response=#<ActionDispatch::Response:0x42355f8 #writer=#<Proc:0x4235550#D:/Informer/ruby/lib/ruby/gems/1.9.1/gems/actionpack-3.0.10/lib/action_dispatch/http/response.rb:43 (lambda)>, #block=nil, #length=0, #header={}, #status=200, #body=[], #cookie=[], #sending_file=false, #blank=false, #cache_control={}, #etag=nil, #request=#<ActionDispatch::Request:0x4235610 ...>>, #_request=#<ActionDispatch::Request:0x4235610 ...>, #_env={...}, #lookup_context=#<ActionView::LookupContext:0x42343c8 #details_key=nil, #details={:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml], :formats=>[:html, :text, :js, :css, :ics, :csv, :xml, :rss, :atom, :yaml, :multipart_form, :url_encoded_form, :json, :flv, :file, :image, :auto, :sourcefile, :sourceimage, :sourceauto, :legacy, :edit], :locale=>[:de, :de]}, #skip_default_locale=false, #frozen_formats=false, #view_paths=[d:/Informer/company/latest/ror/app/views, d:/Informer/company/latest/ror/vendor/plugins/will_paginate/app/views, d:/Informer/company/latest/ror/vendor/plugins/usesguid/app/views, d:/Informer/company/latest/ror/vendor/plugins/acts_as_tree/app/views, d:/Informer/company/latest/ror/vendor/plugins/acts_as_solr/app/views]>, #_action_name="upload", #_response_body=nil, #_config={}, #_params={"document"=>{"id"=>"20", "guid"=>"{ed20ec73-94bc-413b-b3a9-07b44ab6e624}"}, "file"=>{"name"=>"Dokument1.docx", "source"=>#<ActionDispatch::Http::UploadedFile:0x41ced28 #original_filename="Dokument1_201262114815.docx", #content_type="application/octet-stream", #headers="Content-Disposition: form-data; name=\"file[source]\"; filename=\"C:\\Users\\rausch\\AppData\\Roaming\\TQsoft\\InformerOfficeExtension\\Temp\\Dokument1_201262114815.docx\"\r\n Content-Type: application/octet-stream\r\n", #tempfile=#<File:C:/Windows/Temp/RackMultipart20120602-10036-1bfrx5x>>, "pdf"=>#<ActionDispatch::Http::UploadedFile:0x41cec68 #original_filename="Dokument1_201262114815.pdf", #content_type="application/octet-stream", #headers="Content-Disposition: form-data; name=\"file[pdf]\"; filename=\"C:\\Users\\rausch\\AppData\\Roaming\\TQsoft\\InformerOfficeExtension\\Temp\\Dokument1_201262114815.pdf\"\r\n Content-Type: application/octet-stream\r\n", #tempfile=#<File:C:/Windows/Temp/RackMultipart20120602-10036-1uzoxvw>>}, "controller"=>"ioi", "action"=>"upload"}>, "action_dispatch.request.request_parameters"=>{"document"=>{"id"=>"20", "guid"=>"{ed20ec73-94bc-413b-b3a9-07b44ab6e624}"}, "file"=>{"name"=>"Dokument1.docx", "source"=>#<ActionDispatch::Http::UploadedFile:0x41ced28 #original_filename="Dokument1_201262114815.docx", #content_type="application/octet-stream", #headers="Content-Disposition: form-data; name=\"file[source]\"; filename=\"C:\\Users\\rausch\\AppData\\Roaming\\TQsoft\\InformerOfficeExtension\\Temp\\Dokument1_201262114815.docx\"\r\n Content-Type: application/octet-stream\r\n", #tempfile=#<File:C:/Windows/Temp/RackMultipart20120602-10036-1bfrx5x>>, "pdf"=>#<ActionDispatch::Http::UploadedFile:0x41cec68 #original_filename="Dokument1_201262114815.pdf", #content_type="application/octet-stream", #headers="Content-Disposition: form-data; name=\"file[pdf]\"; filename=\"C:\\Users\\rausch\\AppData\\Roaming\\TQsoft\\InformerOfficeExtension\\Temp\\Dokument1_201262114815.pdf\"\r\n Content-Type: application/octet-stream\r\n", #tempfile=#<File:C:/Windows/Temp/RackMultipart20120602-10036-1uzoxvw>>}}, "rack.request.query_string"=>"", "rack.request.query_hash"=>{}, "action_dispatch.request.query_parameters"=>{}, "action_dispatch.request.parameters"=>{"document"=>{"id"=>"20", "guid"=>"{ed20ec73-94bc-413b-b3a9-07b44ab6e624}"}, "file"=>{"name"=>"Dokument1.docx", "source"=>#<ActionDispatch::Http::UploadedFile:0x41ced28 #original_filename="Dokument1_201262114815.docx", #content_type="application/octet-stream", #headers="Content-Disposition: form-data; name=\"file[source]\"; filename=\"C:\\Users\\rausch\\AppData\\Roaming\\TQsoft\\InformerOfficeExtension\\Temp\\Dokument1_201262114815.docx\"\r\n Content-Type: application/octet-stream\r\n", #tempfile=#<File:C:/Windows/Temp/RackMultipart20120602-10036-1bfrx5x>>, "pdf"=>#<ActionDispatch::Http::UploadedFile:0x41cec68 #original_filename="Dokument1_201262114815.pdf", #content_type="application/octet-stream", #headers="Content-Disposition: form-data; name=\"file[pdf]\"; filename=\"C:\\Users\\rausch\\AppData\\Roaming\\TQsoft\\InformerOfficeExtension\\Temp\\Dokument1_201262114815.pdf\"\r\n Content-Type: application/octet-stream\r\n", #tempfile=#<File:C:/Windows/Temp/RackMultipart20120602-10036-1uzoxvw>>}, "controller"=>"ioi", "action"=>"upload"}, "action_dispatch.request.accepts"=>[*/*], "action_dispatch.request.formats"=>[*/*], "action_dispatch.request.flash_hash"=>nil}, #request_method="POST", #filtered_parameters={"document"=>{"id"=>"20", "guid"=>"{ed20ec73-94bc-413b-b3a9-07b44ab6e624}"}, "file"=>{"name"=>"Dokument1.docx", "source"=>#<ActionDispatch::Http::UploadedFile:0x41ced28 #original_filename="Dokument1_201262114815.docx", #content_type="application/octet-stream", #headers="Content-Disposition: form-data; name=\"file[source]\"; filename=\"C:\\Users\\rausch\\AppData\\Roaming\\TQsoft\\InformerOfficeExtension\\Temp\\Dokument1_201262114815.docx\"\r\n Content-Type: application/octet-stream\r\n", #tempfile=#<File:C:/Windows/Temp/RackMultipart20120602-10036-1bfrx5x>>, "pdf"=>#<ActionDispatch::Http::UploadedFile:0x41cec68 #original_filename="Dokument1_201262114815.pdf", #content_type="application/octet-stream", #headers="Content-Disposition: form-data; name=\"file[pdf]\"; filename=\"C:\\Users\\rausch\\AppData\\Roaming\\TQsoft\\InformerOfficeExtension\\Temp\\Dokument1_201262114815.pdf\"\r\n Content-Type: application/octet-stream\r\n", #tempfile=#<File:C:/Windows/Temp/RackMultipart20120602-10036-1uzoxvw>>}, "controller"=>"ioi", "action"=>"upload"}, #method="POST", #fullpath="/ror/ioi/upload">
HTTP_VERSION => HTTP/1.1
HTTP_HOST => thorx64
HTTP_ACCEPT => */*
HTTP_COOKIE => _ror_session=bfd6cdcd0650812edeb58c9a915e3948; user=rausch
HTTP_MAX_FORWARDS => 10
HTTP_X_FORWARDED_FOR => 192.168.14.9
HTTP_X_FORWARDED_HOST => thorx64
HTTP_X_FORWARDED_SERVER => thorx64
HTTP_CONNECTION => Keep-Alive
i am a user?: false
session:
So my question to rails professionals:
So I don't understand why all header data for the ioi/upload request are valid but the rails application do not reuse the session (as you can see the last two line above user => false and session id is empty).
So is there something I have to send again (modify C# client) or is this a rails issue? I think last, but I don't know what to change at the rails part to make the reuse of the session.
Got it!
It was a issue in rails.
This little thing caused the issue :)
application_controller.rb
Line 2: protect_from_forgery
This is to protect the application. Creates a security token to use on every ajax request.
<meta name="csrf-param" content="authenticity_token"/>
<meta name="csrf-token" content="sGeq9l+HfYotFbfuZFHqtmrMGBygMGZc2SjnmEwp9eo="/>
So the solution in this case as I don't have this in the c# client:
Create a handshake to get the security token and post this as well (to much work for me :))
What I did: Add a skip filter in the target controller: skip_before_filter :verify_authenticity_token
Conclusion:
It works to store cookies and headers like I did and send them with the following requests to "simulate" the session.
Related
Karate multi part file upload getting error from Mulesoft
Mulesoft is rejected a file upload saying: "Unable to get name from form-data" According to this link: MuleSoft Support they suggest naming convention of following: Content-Disposition, instead of what is being sent as content-disposition. Feature: Given url 'https:someurlpath' And header Authorization = 'Basic ' + 'feefff' And header Content-Type = 'multipart/form-data' And header Accept-Encoding = 'gzip, deflate, br' And multipart field callingApplicationName = 'Karate' And multipart file binaryContent = { read: 'response.tif', filename: 'response.tif', contentType: 'image/tiff' } And multipart field properties = '[{"displayName":"SR Number","value":["1234","12345"]},{"displayName":"Document Type","value":"CLAI"},{"displayName":"Ingestion Source","value":"FILENETTOOLS"},{"displayName":"Received Date","value":"2022-01-14T00:52:50.837650Z"},{"displayName":"Pages","value":"0"}]' When method Post Then status 200 And print response And match response.status == 'ACTIVE' Here is the request: 1 > POST https://api.maha.com/documents-process-api/v1/documentC/specialR/documents/ 1 > Authorization: Basic foooooooobooooooo 1 > Content-Type: multipart/form-data; boundary=231ef49a739286f9 1 > Accept-Encoding: gzip, deflate, br 1 > Content-Length: 214420 1 > Host: api.maha.com 1 > Connection: Keep-Alive 1 > User-Agent: Apache-HttpClient/4.5.13 (Java/14.0.2) content-disposition: form-data; name="callingApplicationName"; filename="" content-type: text/plain; charset=UTF-8 content-length: 6 Completed: true IsInMemory: true Mixed: content-disposition: form-data; name="binaryContent"; filename="response.tif" content-type: image/tiff; charset=UTF-8 content-length: 213642 Completed: true IsInMemory: false RealFile: /Users/req/workspace/hlx/sasquatch-automated-tests/src/test/groovy/com/maha/gpa/document/storage/service/response.tif DefaultDeleteAfter: true content-disposition: form-data; name="properties"; filename="" content-type: text/plain; charset=UTF-8 content-length: 278 Completed: true IsInMemory: true
Yes this is a known issue with a workaround, refer this thread please: https://github.com/karatelabs/karate/issues/1647 Meanwhile you are most welcome to contribute code to Karate to fix this :)
Why doesn't this code works in getting refresh code from refresh code in oAuth2 stex?
In this question, I managed to obtain an access code and refresh code from stex API Why do I have to specify the redirection URI when using authorization token to get access token in OAuth2? So I surf some web, got authorization code, put the code on my program and I get refresh code. Dim code = "def50200354606432acfb60c836ac40ff440dc2755164756cd7e34ddcf9cd4db8df87cabe71bf5e5c5c278c18c81b0415ba47da34f83ddaab0a84696e1722e266aec2e7942ed86e40e65b0dcf7428aad2747920de6cf8585ce281214f2ecc7353e807640320ca263013387ea0b2d466e2cc31b46c2a2e7b1dd33cdc518efa20b76b752734174f2b500450ed1ccb434611b0bdc458fcfed69a2ab2a5f91242f1f68c504d3151048c49eaf976eff6bbb922dac1acbba069fc8b57fd74069eeadf24c067edf4563aa5ad14b0d9740f1518723ba1c5637164e5e3c4d408102f49c0f63d8f3f5dfbfe11132d242a182e4af3449e811292d1ac69aadf74608a5383b9c4030de3579c98b07c4f087752f7e404f4897d8167b3d8ad266bdb42f74b539cc3fef6ce774edd35d305e655e984028614e50afe760acc754de70986dc7651ac760d5817c665ef1238d0811190763dbfd65993408d12dcf7926be6c71afb5d8a10528c174647934bdd1e4fcf1f4a800b8a74a7ae93bf60b02c602900a981bdb75e9de2b17f359ee" Dim token2 = CookieAwareWebClient.downloadString1("https://api3.stex.com/oauth/token", "grant_type=authorization_code&code=" + code + "&client_id=" + _apiKey1 + "&client_secret=" + _secret1 + "&redirect_uri=https://apidocs.stex.com/oauth2-redirect.html", {}) Dim jtoken1 = JToken.Parse(token2) Dim refreshtoken = jtoken1.Item("refresh_token").ToString This is what I get jtoken1 is {"token_type":"Bearer","expires_in":43200,"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImM2NTdjY2ZlNTg2M2ZjMWYyZDIyZWFhNTY0NDcyOGI4MjU5ODY0MjYxZWI4N2IzYjVkMTY2Y2VmZmU2Y2E2ZDNjNmM0MWE0ZTA3MjA1Nzc0In0.eyJhdWQiOiIxNDQiLCJqdGkiOiJjNjU3Y2NmZTU4NjNmYzFmMmQyMmVhYTU2NDQ3MjhiODI1OTg2NDI2MWViODdiM2I1ZDE2NmNlZmZlNmNhNmQzYzZjNDFhNGUwNzIwNTc3NCIsImlhdCI6MTU1MzUwNjQ5NCwibmJmIjoxNTUzNTA2NDk0LCJleHAiOjE1NTM1NDk2OTQsInN1YiI6IjMxOTgwMSIsInNjb3BlcyI6WyJ0cmFkZSIsInByb2ZpbGUiXX0.PU3Hf06PCfdUQHtTIpCbzWVnA8cCl_Vtt7ecMkif5_HKYbab2z3SjI9EEtbEBMtVzzdCftI26WjjptVdA4oaxEEdM8GYhuGcH30EU8ja1RTxa0LU-jRfFS_eALPf49oFkLcy6UvwZqfTAoDVu3qissC4GRmL-nar9D_5Re2qKcmHnd6Tk7P12ANUjf4URbMC6wy6Zr7Rr7eX9iR87yFqso786599mCmnOyTheBeru-w_j9UFeRXW8UF-oGOYtc2v1qwxsjxMPjZQOrVBdmgiz61MrXFgnaermcjxcWdEL9caJ__-i1991ErU01I3rXJ4xPPxik_4jIwPkhhLnQT73oA-baBycPIjNBja9pPEq-xLCzJgnDIT3A5dtqgjx9eV6Hdmv6lwYr21NfqJLVVQLmToRkDCmMeUXW71uFa77MonGhUkjni4K02kakWJnSQ3IvXgz9ZofV_DUcoxvA0fQmzvGq1_E9_DGBunMJwYNmWByQ0oGvtsZNKCprGtk_4-j1L-wUUds3lviPKDzzpcm7Bgaflpv3y6yeDO_7xW0zwVmfGF6McRaaUCsWyJduR3CnuDmJhs1pAv6CywFjoEZHEFSsqXFLWJVZ6RDU67BzmwV85-kdiZKN1nX6BvoYgYzeyKZpOU_M-jrn2M2DV7ppwXaQauWYHCpF0Gz9doH-U","refresh_token":"def50200517e96e9967aac626d1ca816e6df77cac0b33ab528d0bae8cc4b5fb6475dd9884301017259028365dbcd1abb9f7e00dccc550ce824af672eeacaf291d07805b5e44daa7b18d59f5c4da6db342d9502f54e2330fdfb9cda81177a675cdc68349d9bc974d47a20d6e8de4a7a24dba71bc9c7eb02ff5998628ed4b72688aaf5a8f6cc390208cc799563dbbde53bf411a4aed6106ebbdb7468506eb8ec48dc79581e0af2497eaca8fd06a405f44c18def16e4d9fc6e8569c1f3add3ae87c39836d5e0aa7ca20ec5967baded4aa9a443dc41dbd6aa80b790747aca1d6ceba9ec834ff7f4c9d7534fa9c7b348e8860cca091c7d8cb6b736d699687c6171eeebf3ab762bc6e8066e2b933f0934c80476d9539aca39525424fa4125887ccf70f7295407f7cb9815b6fbb63878afdfe4a3a5808731a12c4f2b4c553763e8ae8df07cad5f21050d164832d3dd426267c8292dc8b3ffce46dc5938f01676be89b67014bfdcb73e5e5c85f9a460cbd52021f8103c3d69b23d2e86a"} and then refreshtoken is "def50200517e96e9967aac626d1ca816e6df77cac0b33ab528d0bae8cc4b5fb6475dd9884301017259028365dbcd1abb9f7e00dccc550ce824af672eeacaf291d07805b5e44daa7b18d59f5c4da6db342d9502f54e2330fdfb9cda81177a675cdc68349d9bc974d47a20d6e8de4a7a24dba71bc9c7eb02ff5998628ed4b72688aaf5a8f6cc390208cc799563dbbde53bf411a4aed6106ebbdb7468506eb8ec48dc79581e0af2497eaca8fd06a405f44c18def16e4d9fc6e8569c1f3add3ae87c39836d5e0aa7ca20ec5967baded4aa9a443dc41dbd6aa80b790747aca1d6ceba9ec834ff7f4c9d7534fa9c7b348e8860cca091c7d8cb6b736d699687c6171eeebf3ab762bc6e8066e2b933f0934c80476d9539aca39525424fa4125887ccf70f7295407f7cb9815b6fbb63878afdfe4a3a5808731a12c4f2b4c553763e8ae8df07cad5f21050d164832d3dd426267c8292dc8b3ffce46dc5938f01676be89b67014bfdcb73e5e5c85f9a460cbd52021f8103c3d69b23d2e86a" Obviously I do not want to hard code authorization code that changes all the time in my program. I suppose I would "store" the refresh code on a file, and then use that refresh code again to get the access code. Is that what I should do? In any case, I look at stex PhP sample, and this is what I see private function getToken($client) { try { if (file_exists(self::JSON_SETTINGS)) { $this->currentToken = json_decode(file_get_contents(self::JSON_SETTINGS)); } else { $this->currentToken = json_decode(json_encode([ 'access_token' => $this->option['tokenObject']['access_token'], 'refresh_token' => $this->option['tokenObject']['refresh_token'], 'expires_in' => null, 'expires_in_date' => null ])); } if ($this->currentToken && $this->currentToken->expires_in_date && date($this->currentToken->expires_in_date) > date("Y-m-d H:i:s", time())) { return $this->currentToken->access_token; } $request = $client->post($this->option['accessTokenUrl'], [ 'form_params' => [ 'grant_type' => 'refresh_token', 'refresh_token' => $this->currentToken->refresh_token, 'client_id' => $this->client_id, 'client_secret' => $this->client_secret, 'scope' => $this->option['scope'], ], ]); $this->currentToken = json_decode($request->getBody()); $this->currentToken->expires_in_date = date("Y-m-d H:i:s", time() + $this->currentToken->expires_in); file_put_contents(self::JSON_SETTINGS, json_encode($this->currentToken)); } catch (\Exception $e) { throw new \Error($e->getMessage()); } return $this->currentToken->access_token; } It seems that stex sample code which you can get here https://github.com/StocksExchange/php-client somehow already "know" a refresh_token. I look at the code, and I have no idea how they get their refresh_token initially. However, it seems that once you got a refresh_token, you can keep getting it. I wonder if the refresh_token changes all the time every time we ask for another one. In any case, I try to get another access token just after I get my first one. I do this Dim token1 = CookieAwareWebClient.downloadString1("https://api3.stex.com/oauth/token", "grant_type=refresh_token&refreshtoken=" + refreshtoken + "&client_id=" + _apiKey1 + "&client_secret=" + _secret1 + "&scope=trade%20profile&redirect_uri=https://apidocs.stex.com/oauth2-redirect.html", {}) And I get 400 error. Bad request. The code basically does a post without any additional headers. Similar code worked fine when I was getting my first access token. Additional Info: Stex have Swagger UI. If I do live http header this is how they got the access token. However, the Swagger UI doesn't try to get another refresh token. So I don't exactly know how to do so. You can check here https://apidocs.stex.com/ https://app.stex.com/oauth/authorize?response_type=code&client_id=144&redirect_uri=https%3A%2F%2Fapidocs.stex.com%2Foauth2-redirect.html&scope=trade profile&state=VHVlIEFwciAwOSAyMDE5IDAyOjE2OjA5IEdNVCswNzAwIChJbmRvY2hpbmEgVGltZSk%3D Host: app.stex.com User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate, br Referer: https://apidocs.stex.com/ Connection: keep-alive Cookie: __cfduid=daa1f8ce90555ce6c4dbdb67819ccf58a1551861370; last_pair=eyJpdiI6IjAzWVpZazN2Y29JR1Z0REVYRmZQV2c9PSIsInZhbHVlIjoiN215Rm0yRHRVSlwvSUp0QXVzeUtGRnc9PSIsIm1hYyI6ImY5ZjI1Y2UxYzFlZDc0ZWVjMTkwMzM5Mjk0ZDljODJmM2EzNjBmNmQ4NzU3YzRlMmI3MTkyYjQwMTc0YzIzZmUifQ%3D%3D; intercom-id-qr8nd1jy=196680cc-0ef5-490c-8577-22b345175726; stex_session=eyJpdiI6ImFkNFB3cFB3c05JYXdqK21xVUtPZnc9PSIsInZhbHVlIjoiYlhRemEwZGlVOWdLXC9NWlk1Skc1aHFOam1SMDV5UHg4N3hhdE51T2J3dk13MVQxWmZxcHFyMVNkMFBqUkQzaU0iLCJtYWMiOiI2YWQ1Y2Q1OTlhODA5MjVmMTM2ZWY2ODNlN2QzYTMwYjBkZTc2NDUxZWU5OTE5MTc1Zjk2NjY0ZWEzMDM5ZWExIn0%3D; XSRF-TOKEN=eyJpdiI6InZIREhTMDdsTVpQSzRNYnI1YlZNR3c9PSIsInZhbHVlIjoiQm9Uc1BleGE0dnpmeXhyUFV6c21DWnQ4VWhrc0VVQ1AzUFhwN2twK2g1WEhRME1yM1JBV0pKd1RLYzJQaWhwbSIsIm1hYyI6Ijk5ODM5YTFjZDA5YTFmMGQzZWYzZDM0OWE2ZjAzNWNmNGVjNGVkNDA4ZWI1NWUwN2JiYTZjMDdlNTdkNzVjYmYifQ%3D%3D Upgrade-Insecure-Requests: 1 GET: HTTP/2.0 302 Found date: Mon, 08 Apr 2019 19:16:09 GMT content-type: text/html; charset=UTF-8 location: https://apidocs.stex.com/oauth2-redirect.html?code=def5020028f086b604ecddce0d8eba73f7b3c8003a6052a4786bf37deeeff4fa518c86288f96fcf9842d64f848465f987727e0fe206594287cc88bd427b447b6a928548f6af48f21fea3958f180fe6aad0e31aef102b2f1316e7f0a307042f41432ebaf5fbf26410008c16f1ebc5a1b5f42b90cb8eb184c84e75b153d9c820a7f4953fe02ab864200c5fda9cb98dcc114ee2b54caf36f6177b15cee04ef45a24f28d387b80e0000c7c120f8bdd66260f8d7f733f5ce5686c9257d4fa86095ce96c38c6bcdc92a7f510a3a4f1a3c36a561d71dd5be741cbd1df336d1dcbbfef323bc8879f639795d3d185ea081aa42e97d8db0fe76d085f99265025c8e1da6402f93cf037256b6d80b4ca0ab44a7b5db00e46260f620113646b3872eaca0219062c5e6edbfd890a68525083240ee96f86c4ab3a5e3a70d902f747fa38e0875b5a67964f14a5510c5eda8cd9f423096f82f240efa96d620f19f12206eb007a80099ebd5deba58bc574bbecb32fb2f4d2e6da1583bbe0901bc2515d61b29efd8e11e8f7a58854b1d0&state=VHVlIEFwciAwOSAyMDE5IDAyOjE2OjA5IEdNVCswNzAwIChJbmRvY2hpbmEgVGltZSk%3D cache-control: private, must-revalidate pragma: no-cache expires: -1 x-xss-protection: 1; mode=block set-cookie: XSRF-TOKEN=eyJpdiI6IngxelBQOGFhd1NtYUlJc3JncG5jU2c9PSIsInZhbHVlIjoiK3dtSzZvSHRBUzNaQ0ZFdm1EanNBMkJINERlSGQrbWxSdjYzN2NJaDBESVBuQU1oU3FtTHM3cVFyWHBlWCs1USIsIm1hYyI6ImU3NzA2NWY0ZjUyYWFmZmI4NDFlODM4ZTY4NDcxNmQ3N2Q0MWYzYjI3OTkxM2U0ZDIzMjE4MDVjMDBhYjYzMjcifQ%3D%3D; expires=Tue, 09-Apr-2019 07:16:09 GMT; Max-Age=43200; path=/; domain=stex.com stex_session=eyJpdiI6IkJscWhhVVlHY3JHSUx0RVhRREMwSEE9PSIsInZhbHVlIjoiS1BwQnNySzBOOVdrU3lvTFhYSzg4NVgrRjlPVm9MTHJ2SEluaVZCWTVTeCtpWm53RkxPSGxBcmUzMGV6QzBcL3UiLCJtYWMiOiJmZjljZDk5YzBlMzRiMDQ2NDM2MDA1MWUyMTAxNzI4ZjRlMmE4MGQ3NGI5Y2Y0NjA3MzA0ODNlOTcyOWRmZTIxIn0%3D; expires=Tue, 09-Apr-2019 07:16:09 GMT; Max-Age=43200; path=/; domain=stex.com; httponly expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" server: cloudflare cf-ray: 4c4692f3dbf9c379-SIN X-Firefox-Spdy: h2 https://apidocs.stex.com/oauth2-redirect.html?code=def5020028f086b604ecddce0d8eba73f7b3c8003a6052a4786bf37deeeff4fa518c86288f96fcf9842d64f848465f987727e0fe206594287cc88bd427b447b6a928548f6af48f21fea3958f180fe6aad0e31aef102b2f1316e7f0a307042f41432ebaf5fbf26410008c16f1ebc5a1b5f42b90cb8eb184c84e75b153d9c820a7f4953fe02ab864200c5fda9cb98dcc114ee2b54caf36f6177b15cee04ef45a24f28d387b80e0000c7c120f8bdd66260f8d7f733f5ce5686c9257d4fa86095ce96c38c6bcdc92a7f510a3a4f1a3c36a561d71dd5be741cbd1df336d1dcbbfef323bc8879f639795d3d185ea081aa42e97d8db0fe76d085f99265025c8e1da6402f93cf037256b6d80b4ca0ab44a7b5db00e46260f620113646b3872eaca0219062c5e6edbfd890a68525083240ee96f86c4ab3a5e3a70d902f747fa38e0875b5a67964f14a5510c5eda8cd9f423096f82f240efa96d620f19f12206eb007a80099ebd5deba58bc574bbecb32fb2f4d2e6da1583bbe0901bc2515d61b29efd8e11e8f7a58854b1d0&state=VHVlIEFwciAwOSAyMDE5IDAyOjE2OjA5IEdNVCswNzAwIChJbmRvY2hpbmEgVGltZSk%3D Host: apidocs.stex.com User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate, br Referer: https://apidocs.stex.com/ Connection: keep-alive Cookie: __cfduid=daa1f8ce90555ce6c4dbdb67819ccf58a1551861370; last_pair=eyJpdiI6IjAzWVpZazN2Y29JR1Z0REVYRmZQV2c9PSIsInZhbHVlIjoiN215Rm0yRHRVSlwvSUp0QXVzeUtGRnc9PSIsIm1hYyI6ImY5ZjI1Y2UxYzFlZDc0ZWVjMTkwMzM5Mjk0ZDljODJmM2EzNjBmNmQ4NzU3YzRlMmI3MTkyYjQwMTc0YzIzZmUifQ%3D%3D; intercom-id-qr8nd1jy=196680cc-0ef5-490c-8577-22b345175726; stex_session=eyJpdiI6IkJscWhhVVlHY3JHSUx0RVhRREMwSEE9PSIsInZhbHVlIjoiS1BwQnNySzBOOVdrU3lvTFhYSzg4NVgrRjlPVm9MTHJ2SEluaVZCWTVTeCtpWm53RkxPSGxBcmUzMGV6QzBcL3UiLCJtYWMiOiJmZjljZDk5YzBlMzRiMDQ2NDM2MDA1MWUyMTAxNzI4ZjRlMmE4MGQ3NGI5Y2Y0NjA3MzA0ODNlOTcyOWRmZTIxIn0%3D; XSRF-TOKEN=eyJpdiI6IngxelBQOGFhd1NtYUlJc3JncG5jU2c9PSIsInZhbHVlIjoiK3dtSzZvSHRBUzNaQ0ZFdm1EanNBMkJINERlSGQrbWxSdjYzN2NJaDBESVBuQU1oU3FtTHM3cVFyWHBlWCs1USIsIm1hYyI6ImU3NzA2NWY0ZjUyYWFmZmI4NDFlODM4ZTY4NDcxNmQ3N2Q0MWYzYjI3OTkxM2U0ZDIzMjE4MDVjMDBhYjYzMjcifQ%3D%3D Upgrade-Insecure-Requests: 1 GET: HTTP/2.0 200 OK date: Mon, 08 Apr 2019 19:16:09 GMT content-type: text/html; charset=UTF-8 cache-control: max-age=3600 last-modified: Sat, 12 Jan 2019 07:08:55 GMT x-frame-options: DENY expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" server: cloudflare cf-ray: 4c4692f74f62c379-SIN content-encoding: gzip X-Firefox-Spdy: h2 https://apidocs.stex.com/favicon.ico NS_BINDING_ABORTED https://api3.stex.com/oauth/token Host: api3.stex.com User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: application/json, text/plain, */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate, br Referer: https://apidocs.stex.com/ Content-Type: application/x-www-form-urlencoded Origin: https://apidocs.stex.com Content-Length: 953 Connection: keep-alive grant_type=authorization_code&code=def5020028f086b604ecddce0d8eba73f7b3c8003a6052a4786bf37deeeff4fa518c86288f96fcf9842d64f848465f987727e0fe206594287cc88bd427b447b6a928548f6af48f21fea3958f180fe6aad0e31aef102b2f1316e7f0a307042f41432ebaf5fbf26410008c16f1ebc5a1b5f42b90cb8eb184c84e75b153d9c820a7f4953fe02ab864200c5fda9cb98dcc114ee2b54caf36f6177b15cee04ef45a24f28d387b80e0000c7c120f8bdd66260f8d7f733f5ce5686c9257d4fa86095ce96c38c6bcdc92a7f510a3a4f1a3c36a561d71dd5be741cbd1df336d1dcbbfef323bc8879f639795d3d185ea081aa42e97d8db0fe76d085f99265025c8e1da6402f93cf037256b6d80b4ca0ab44a7b5db00e46260f620113646b3872eaca0219062c5e6edbfd890a68525083240ee96f86c4ab3a5e3a70d902f747fa38e0875b5a67964f14a5510c5eda8cd9f423096f82f240efa96d620f19f12206eb007a80099ebd5deba58bc574bbecb32fb2f4d2e6da1583bbe0901bc2515d61b29efd8e11e8f7a58854b1d0&client_id=144&client_secret=lcUPy7ANJ0rkqkvt25JQdJoL3w4hYsyX3SWP97jL&redirect_uri=https://apidocs.stex.com/oauth2-redirect.html POST: HTTP/2.0 200 OK date: Mon, 08 Apr 2019 19:16:11 GMT content-type: application/json; charset=UTF-8 pragma: no-cache cache-control: no-store, private x-ratelimit-limit: 60 x-ratelimit-remaining: 59 access-control-allow-origin: https://apidocs.stex.com vary: Origin access-control-allow-credentials: true set-cookie: __cfduid=dd6ab0090b96f4be963967df030a6784e1554750970; expires=Tue, 07-Apr-20 19:16:10 GMT; path=/; domain=.stex.com; HttpOnly; Secure stex_session=eyJpdiI6IkhheHYyMXJ4SjBHY0c3dUFsUG9UVGc9PSIsInZhbHVlIjoiZG1hTmJIRWlJNERTYzBMaVJ5bHJTYjFGNkZwRVwvNjRVZ2JkaE9ub2dVMm1XSzJKQ3NPZ0V5VEk3MG0rcWJXQ3IiLCJtYWMiOiJiNTc4ZjNkZDhmZWMyYzM5MWMxNjU5NzdhZGFmNjI1MzYxOWI2ZTU5MWFjOTQ3ZTdiMTI4MTFmYWJhZmEzOWNlIn0%3D; expires=Tue, 09-Apr-2019 07:16:11 GMT; Max-Age=43200; path=/; domain=stex.com; httponly x-xss-protection: 1; mode=block expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" server: cloudflare cf-ray: 4c4692fd3b4cc338-SIN content-encoding: gzip X-Firefox-Spdy: h2 I still get 400 error. The code token that I managed to get is the following {{ "token_type": "Bearer", "expires_in": 43200, "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImQ2Y2Y5MWFlNDc3NGIwNWIyNjk3ZjYzZDRkNzE4M2M3ODExNGJhOTZlN2EzMzdlYWI2NmQxMjY2MWNmMTFiYmRhMWY3ODA2YTNjYWVkN2ZlIn0.eyJhdWQiOiIxNDQiLCJqdGkiOiJkNmNmOTFhZTQ3NzRiMDViMjY5N2Y2M2Q0ZDcxODNjNzgxMTRiYTk2ZTdhMzM3ZWFiNjZkMTI2NjFjZjExYmJkYTFmNzgwNmEzY2FlZDdmZSIsImlhdCI6MTU1NDc1MDM0NywibmJmIjoxNTU0NzUwMzQ3LCJleHAiOjE1NTQ3OTM1NDcsInN1YiI6IjMxOTgwMSIsInNjb3BlcyI6WyJ0cmFkZSIsInByb2ZpbGUiXX0.buJmntuGIaVjlXRfycplmQ9nlt_X8onH6rvb-7gy_4wQggG19AlivLEafrIY-qSGx0G89cT3ebaDmS_4PD2b_0bB_8BPVwB9sUSJxTvDK8XheI75wK9VSklaOKPSEXIN7FJfq2rHgy_V432Q_wGVAWp892ic8f6MoBw1UfhfT5ev6B6qbBzONf0Gywf0yTCyy5mmZY2B3Fi-c9e-_b0pzicKYRuwxOU5K98FT3QG3HpA9TzD5mumy0cmoBa-7kT3n2kQXosjZi959Yxe_r4KHD2WzsQpsMpq-NKndbCTOsgZh3fi3N8TitHSefgBeOCRPE2QDp_jDE3y_RtJ9Yk-d9vcknazS269s7lxe6YJxblzTY-lGK_hR6NE2HkiveLtZU6dC34TjtaryReACaepoKbnpwKGCYR_kWnQYxT0aThqYcKRsySrEuNII2O04_ZXc4I990bnKfdffGoawoZS0qzjoFRkdSzOBj3wKJYADCb1DyibBPTg6ADTV9Tb28Hb_nHRD-fIciFSqmCOHN58jx8Dv0jbgjPOhthcLCT90Ywy82_NTC9kUFaD1o0kulwYKjMxEHtP4EjNBnSMNUaqC7uV__nuZhHFhKCMgRIQRZN2VTx76HVKcjpS-LuuYXs6bp4RcRmZ1LMRT__7h025llJSI4i6DHwc-4Me1s2X3SU", "refresh_token": "def50200fd6c6c2abefc561758aa2ed9cd94e7aa84849b508fd103e85f3146881539aa2612e6c82ef838c1826202ada55a440a7d3a0f9c0e10fd085e10901cbdf700059ef7eb36b2dd56c290052aa7b36b3858258e3c4596b63aac660a318da6c01aed58689e7f5b7d8830ab604a9cb98dd16e70041cb336d9626ec5ba9f05dad26f4a071c8d8b47805c777aa747a3bda1b0b4f53ce3cbfe04f6bbb6125a1523ba28e0efdced3048733870da562d7c07b115315faf673be4dfc764c2223f13eaa728b4330c5c7d332c64e348e9a38f3019c8aaedb94e656bea89793388a18beae1378bcaab629b70798f762395eac888b965a26ef507869aa1fa2ae4a4a83a42e53d655f47429efe96e8cac5aac7309c3f9a340ee6a6b7d9c3bd0bb24330147e1b254ebae9422cc557773e062b09455583c09d933ebda34d64dc5da4c84e7ad310903e467a0fc0d1492e9fc5f866730bf9a6d9035de80e8185001d1b81e376230f08d7e2953287e256181dc598f9966783bc25aa81181c5787"}} The code I used to get another refresh token is Dim post = "grant_type=refresh_token&refreshtoken=" + refreshtoken + "&client_id=" + _apiKey1 + "&client_secret=" + _secret1 + "&scope=trade profile" 'post = grant_type=refresh_token&refreshtoken=def50200fd6c6c2abefc561758aa2ed9cd94e7aa84849b508fd103e85f3146881539aa2612e6c82ef838c1826202ada55a440a7d3a0f9c0e10fd085e10901cbdf700059ef7eb36b2dd56c290052aa7b36b3858258e3c4596b63aac660a318da6c01aed58689e7f5b7d8830ab604a9cb98dd16e70041cb336d9626ec5ba9f05dad26f4a071c8d8b47805c777aa747a3bda1b0b4f53ce3cbfe04f6bbb6125a1523ba28e0efdced3048733870da562d7c07b115315faf673be4dfc764c2223f13eaa728b4330c5c7d332c64e348e9a38f3019c8aaedb94e656bea89793388a18beae1378bcaab629b70798f762395eac888b965a26ef507869aa1fa2ae4a4a83a42e53d655f47429efe96e8cac5aac7309c3f9a340ee6a6b7d9c3bd0bb24330147e1b254ebae9422cc557773e062b09455583c09d933ebda34d64dc5da4c84e7ad310903e467a0fc0d1492e9fc5f866730bf9a6d9035de80e8185001d1b81e376230f08d7e2953287e256181dc598f9966783bc25aa81181c5787&client_id=144&client_secret=lcUPy7ANJ0rkqkvt25JQdJoL3w4hYsyX3SWP97jL&scope=trade profile Dim token1 = CookieAwareWebClient.downloadString1("https://api3.stex.com/oauth/token", post, {}) Notice I didn't encode the space between trade and profile. Encoding it doesn't help. In fact, if anyone can try creating an API for STEX and try it themselves it'll be great. Another Update: The error I got is error 400 invalid_request This error occurs when there is a missing parameter that includes multiple credentials, unsupported parameter value. https://www.tutorialspoint.com/oauth2.0/access_token_error_response_codes.htm The code I used to get the new access token with refresh token is Dim post = "grant_type=refresh_token&refreshtoken=" + refreshToken + "&client_id=" + _apiKey1 + "&client_secret=" + _secret1 + "&scope=trade profile" 'post = grant_type=refresh_token&refreshtoken=def5020046875925bb9c0ba2ead1954836339f8f31d5a45103603b857567096da0eb820114a75a6ed3db9eb301e3389d284a696a3cb21ea0df9eebdca2052e8b8120423bb2d4b063651aeff7ac7623ea3beea2f3f21b5127792daf6f71f4d23980ca140f875ec5607f63deeac8696128ea2918a473486c0c4223a088f385046b84e6f8edd17cb459d5cdc66d856ee42b2ce3f90f3829a104735372ac14eae3ccff71dde4552b9ad46df7380870b5cd3bcb8d6ca7f16484a2d5b3b26efcebf7b2e5221ed16620445099ee4b0239fd82c8e7f37262883d57fc6545ab31f9e52dc4fc4de70235d5121f7222f8066bfdc9945aa9f3bac0c3068c9dac5940c6e2fdc9daa6623a9f2b6e3f41aa47698ec1008514878494fef9932b317f42873af44d5dbcdd19958c2fc3835a820d09e5aa6a6ae3bef6592812a698b2547f0cca5e9f8ac38014b6651be46a098374f92bc35fcebc373f17ab70fd20cf1147bf11e2093e9908516717a3902d2d9efc7f06e917fb67dca2bca4f0c25ed7&client_id=144&client_secret=lcUPy7ANJ0rkqkvt25JQdJoL3w4hYsyX3SWP97jL&scope=trade profile tokenstring = CookieAwareWebClient.downloadString1("https://api3.stex.com/oauth/token", post, {}) saveJtoken(tokenstring) jtoken1 = JObject.Parse(tokenstring) 'reparse tokenstring with new string From that code the parameters I sent is grant_type=refresh_token refreshtoken=def5020046875925bb9c0ba2ead1954836339f8f31d5a45103603b857567096da0eb820114a75a6ed3db9eb301e3389d284a696a3cb21ea0df9eebdca2052e8b8120423bb2d4b063651aeff7ac7623ea3beea2f3f21b5127792daf6f71f4d23980ca140f875ec5607f63deeac8696128ea2918a473486c0c4223a088f385046b84e6f8edd17cb459d5cdc66d856ee42b2ce3f90f3829a104735372ac14eae3ccff71dde4552b9ad46df7380870b5cd3bcb8d6ca7f16484a2d5b3b26efcebf7b2e5221ed16620445099ee4b0239fd82c8e7f37262883d57fc6545ab31f9e52dc4fc4de70235d5121f7222f8066bfdc9945aa9f3bac0c3068c9dac5940c6e2fdc9daa6623a9f2b6e3f41aa47698ec1008514878494fef9932b317f42873af44d5dbcdd19958c2fc3835a820d09e5aa6a6ae3bef6592812a698b2547f0cca5e9f8ac38014b6651be46a098374f92bc35fcebc373f17ab70fd20cf1147bf11e2093e9908516717a3902d2d9efc7f06e917fb67dca2bca4f0c25ed7 client_id=144 client_secret=lcUPy7ANJ0rkqkvt25JQdJoL3w4hYsyX3SWP97jL scope=trade profile
Looking at their code, you have to have already done the OAuth2 initialization BEFORE you use their API. Once you've done that, their API saves the entire token (access/refresh/expiry) to the settings.json file. I would try the following: Remove the redirect_uri from the refresh request: I've seen these fail if you add parameters that the implementation isn't expecting Check that the scope(s) you are requesting for the refresh match the scopes you were originally granted Ensure you're not requesting the refresh too early: I've seen services that only let you request the refresh token within a certain time of or after the actual expiry. In their source they only ask for a refresh after the token has expired.
It finally works. Why? I look at this code Dim post = "grant_type=refresh_token&refreshtoken=" + refreshToken + "&client_id=" + _apiKey1 + "&client_secret=" + _secret1 + "&scope=trade profile" There should be an _ between refresh and token. It should be "grant_type=refresh_token&refresh_token="
REST API response with 400 Bad request when Content-length header is givin in POST
I have a Website and a python flask RESTFUL API. When testing the API with Postman it works just fine, but the same request using XMLHttprequest in js gives me a 400 BAD Request code. I looked at the headers send and replicated the XMLHttprequest headers in Postman, to get a 400 BAD REQUEST Code. If i remove the Content-Length header from the request, it works fine. My Postman code (HTML, without content-length): POST /user/181453766040485888 HTTP/1.1 Host: 127.0.0.1:5000 Content-Type: multipart/form-data; boundary=--- -WebKitFormBoundary7MA4YWxkTrZu0gW Accept: */* Accept-Encoding: gzip, deflate, br Accept-Language: en-US,en;q=0.9 Connection: keeep-alive Host: 127.0.0.1:5000 Origin: http://localhost:52014 Referer: http://localhost:52014/settings.php User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 OPR/57.0.3098.106 (Edition Campaign 76) cache-control: no-cache Postman-Token: 5dd34b0b-965c-4d31-83b9-2364b03c0aa2 Content-Disposition: form-data; name="status" 0 Content-Disposition: form-data; name="username" 0 Content-Disposition: form-data; name="token" 0 Content-Disposition: form-data; name="display_names" 1 Content-Disposition: form-data; name="messages" 1 Content-Disposition: form-data; name="roles" 1 Content-Disposition: form-data; name="votes" 1 ------WebKitFormBoundary7MA4YWxkTrZu0gW-- My js function (for testing): function save() { var formData = new FormData(); formData.append("status", 0); formData.append("username", 0); formData.append("token", 0); formData.append("display_names", 0); formData.append("messages", 0); formData.append("roles", 0); formData.append("votes", 0); const Http = new XMLHttpRequest(); const url='http://127.0.0.1:5000/user/181453766040485888'; Http.open("POST", url); Http.onreadystatechange=(e)=>{ console.log(Http.responseText) } Http.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); Http.send(formData); } my API function that handles the request (abstract): def post(self, id): if database.execute(database.SAVE_USER_SETTINGS.format(id, request.form["status"], request.form["username"], request.form["token"], request.form["display_names"], request.form["messages"], request.form["roles"], request.form["votes"])): return (id, request.form["status"], request.form["username"], request.form["token"], request.form["display_names"], request.form["messages"], request.form["roles"], request.form["votes"]), 201 return {}, 500
Unable to proceed after clicking a button
I am using spectron to simulate a test on Slack as follows: 1) Open the application. 2) Type in a valid domain. 3) Click Continue. I am using the following script for that purpose: JavaScript: var Application = require('spectron').Application var assert = require('assert') var app = new Application({ path: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome' }) app.start().then(function() { // Check if the window is visible return app.browserWindow.isVisible() }).then(function(isVisible) { // Verify the window is visible assert.equal(isVisible, true) }).then(function() { // Get the window's title return app.client.getTitle() }).then(function(title) { // Verify the window's title // assert.equal(title, 'My App') }).catch(function(error) { // Log any failures console.error('Test failed', error.message) }).then(function() { // Stop the application // return app.stop() }) console.log('Before setTimeout'); setTimeout(function() { console.log('Inside setTimeout'); return app.client.waitUntilWindowLoaded() .windowHandles().then(function(session) { // Need to return the promise back, if promise is // it would wait for the state or else app will exit. console.log('Before switchTab, click & keys'); app.client.switchTab(session.value[1]).click('#domain').keys('testing').click("#submit_team_domain") .catch(function(error) { console.error('error message->', error.message); }); console.log('After switchTab, click & keys'); }); }, 5000); Java: Set<String> windowHandles = webDriver.getWindowHandles(); Iterator<String> iterator = windowHandles.iterator(); while (iterator.hasNext()) { String windowHandle = iterator.next(); if (!windowHandle.equalsIgnoreCase(webDriver.getWindowHandle())) webDriver.switchTo().window(windowHandle); } try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } WebElement textBox = webDriver.findElement(By.id("domain")); textBox.click(); textBox.sendKeys("testing"); WebElement button = webDriver.findElement(By.id("submit_team_domain")); button = webDriver.findElement(By.id("submit_team_domain")); button.click(); I am testing with and without a selenium server between a Mac and a Linux machine. The expected result should be that the page should proceed after clicking continue. What is actually happening is that if a valid domain is provided then it gets stuck and never proceeds. The only exception to this is when we use Spectron to test without a Selenium server on a Linux machine, which itself fails about 20% of the time. If we provide an invalid domain in any of the cases, it simply proceeds. Following are the logs when using Spectron without a Selenium Server: requestOptions -> {"path":"/session/:sessionId/element"} data -> {"using":"id","value":"domain"} _ref -> {"body":{"sessionId":"bc8bc9abd7a9827258cee72de70d835f","status":0,"value":{"ELEMENT":"0.006260871409230262-1"}},"response":{"statusCode":200,"body":{"sessionId":"bc8bc9abd7a9827258cee72de70d835f","status":0,"value":{"ELEMENT":"0.006260871409230262-1"}},"headers":{"content-length":"104","content-type":"application/json; charset=utf-8","connection":"close"},"request":{"uri":{"protocol":"http:","slashes":true,"auth":null,"host":"127.0.0.1:9515","port":"9515","hostname":"127.0.0.1","hash":null,"search":null,"query":null,"pathname":"/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/element","path":"/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/element","href":"http://127.0.0.1:9515/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/element"},"method":"POST","headers":{"Connection":"keep-alive","Accept":"application/json","User-Agent":"webdriverio/webdriverio/4.6.2","Content-Type":"application/json; charset=UTF-8","Content-Length":31}}}} requestOptions -> {"path":"/session/:sessionId/element/0.006260871409230262-1/click","method":"POST"} data -> {} _ref -> {"body":{"sessionId":"bc8bc9abd7a9827258cee72de70d835f","status":0,"value":null},"response":{"statusCode":200,"body":{"sessionId":"bc8bc9abd7a9827258cee72de70d835f","status":0,"value":null},"headers":{"content-length":"72","content-type":"application/json; charset=utf-8","connection":"close"},"request":{"uri":{"protocol":"http:","slashes":true,"auth":null,"host":"127.0.0.1:9515","port":"9515","hostname":"127.0.0.1","hash":null,"search":null,"query":null,"pathname":"/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/element/0.006260871409230262-1/click","path":"/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/element/0.006260871409230262-1/click","href":"http://127.0.0.1:9515/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/element/0.006260871409230262-1/click"},"method":"POST","headers":{"Connection":"keep-alive","Accept":"application/json","User-Agent":"webdriverio/webdriverio/4.6.2","content-type":"application/json","content-length":2}}}} WARNING: the "keys" command will be depcrecated soon. Please use a different command in order to avoid failures in your test after updating WebdriverIO. requestOptions -> {"path":"/session/:sessionId/keys"} data -> {"value":["c","o","s","m","o","t","e","s","t","i","n","g"]} _ref -> {"body":{"sessionId":"bc8bc9abd7a9827258cee72de70d835f","status":0,"value":null},"response":{"statusCode":200,"body":{"sessionId":"bc8bc9abd7a9827258cee72de70d835f","status":0,"value":null},"headers":{"content-length":"72","content-type":"application/json; charset=utf-8","connection":"close"},"request":{"uri":{"protocol":"http:","slashes":true,"auth":null,"host":"127.0.0.1:9515","port":"9515","hostname":"127.0.0.1","hash":null,"search":null,"query":null,"pathname":"/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/keys","path":"/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/keys","href":"http://127.0.0.1:9515/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/keys"},"method":"POST","headers":{"Connection":"keep-alive","Accept":"application/json","User-Agent":"webdriverio/webdriverio/4.6.2","Content-Type":"application/json; charset=UTF-8","Content-Length":59}}}} requestOptions -> {"path":"/session/:sessionId/element"} data -> {"using":"id","value":"submit_team_domain"} _ref -> {"body":{"sessionId":"bc8bc9abd7a9827258cee72de70d835f","status":0,"value":{"ELEMENT":"0.006260871409230262-2"}},"response":{"statusCode":200,"body":{"sessionId":"bc8bc9abd7a9827258cee72de70d835f","status":0,"value":{"ELEMENT":"0.006260871409230262-2"}},"headers":{"content-length":"104","content-type":"application/json; charset=utf-8","connection":"close"},"request":{"uri":{"protocol":"http:","slashes":true,"auth":null,"host":"127.0.0.1:9515","port":"9515","hostname":"127.0.0.1","hash":null,"search":null,"query":null,"pathname":"/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/element","path":"/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/element","href":"http://127.0.0.1:9515/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/element"},"method":"POST","headers":{"Connection":"keep-alive","Accept":"application/json","User-Agent":"webdriverio/webdriverio/4.6.2","Content-Type":"application/json; charset=UTF-8","Content-Length":43}}}} requestOptions -> {"path":"/session/:sessionId/element/0.006260871409230262-2/click","method":"POST"} data -> {} _ref -> {"body":{"sessionId":"bc8bc9abd7a9827258cee72de70d835f","status":0,"value":null},"response":{"statusCode":200,"body":{"sessionId":"bc8bc9abd7a9827258cee72de70d835f","status":0,"value":null},"headers":{"content-length":"72","content-type":"application/json; charset=utf-8","connection":"close"},"request":{"uri":{"protocol":"http:","slashes":true,"auth":null,"host":"127.0.0.1:9515","port":"9515","hostname":"127.0.0.1","hash":null,"search":null,"query":null,"pathname":"/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/element/0.006260871409230262-2/click","path":"/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/element/0.006260871409230262-2/click","href":"http://127.0.0.1:9515/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/element/0.006260871409230262-2/click"},"method":"POST","headers":{"Connection":"keep-alive","Accept":"application/json","User-Agent":"webdriverio/webdriverio/4.6.2","content-type":"application/json","content-length":2}}}} Following are the logs when using Java Language Bindings with a Selenium Server: 15:11:43.884 INFO - Found handler: org.openqa.selenium.remote.server.ServicedSession#5d54be3a 15:11:43.884 INFO - Handler thread for session 976706a5ace12e22ec54d9848f21813c (chrome): Executing POST on /session/976706a5ace12e22ec54d9848f21813c/element (handler: ServicedSession) 15:11:43.885 INFO - To upstream: {"using":"id","value":"domain"} 15:11:43.885 DEBUG - sun.net.www.MessageHeader#55edb1c210 pairs: {POST /session/976706a5ace12e22ec54d9848f21813c/element HTTP/1.1: null}{User-Agent: Apache-HttpClient/4.5.3 (Java/1.8.0_151)}{Accept-Encoding: gzip,deflate}{Content-Type: application/json; charset=utf-8}{Connection: close}{Cache-Control: no-cache}{Pragma: no-cache}{Host: localhost:25846}{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}{Content-Length: 31} 15:11:43.908 DEBUG - sun.net.www.MessageHeader#61b2a16b4 pairs: {null: HTTP/1.1 200 OK}{Content-Length: 102}{Content-Type: application/json; charset=utf-8}{Connection: close} 15:11:43.908 INFO - To downstream: {"sessionId":"976706a5ace12e22ec54d9848f21813c","status":0,"value":{"ELEMENT":"0.8306467617329649-1"}} 15:11:43.917 INFO - Found handler: org.openqa.selenium.remote.server.ServicedSession#5d54be3a 15:11:43.917 INFO - Handler thread for session 976706a5ace12e22ec54d9848f21813c (chrome): Executing POST on /session/976706a5ace12e22ec54d9848f21813c/element/0.8306467617329649-1/click (handler: ServicedSession) 15:11:43.918 INFO - To upstream: {"id":"0.8306467617329649-1"} 15:11:43.919 DEBUG - sun.net.www.MessageHeader#3cbdbdb110 pairs: {POST /session/976706a5ace12e22ec54d9848f21813c/element/0.8306467617329649-1/click HTTP/1.1: null}{User-Agent: Apache-HttpClient/4.5.3 (Java/1.8.0_151)}{Accept-Encoding: gzip,deflate}{Content-Type: application/json; charset=utf-8}{Connection: close}{Cache-Control: no-cache}{Pragma: no-cache}{Host: localhost:25846}{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}{Content-Length: 29} 15:11:43.986 DEBUG - sun.net.www.MessageHeader#32f13174 pairs: {null: HTTP/1.1 200 OK}{Content-Length: 72}{Content-Type: application/json; charset=utf-8}{Connection: close} 15:11:43.986 INFO - To downstream: {"sessionId":"976706a5ace12e22ec54d9848f21813c","status":0,"value":null} 15:11:43.991 INFO - Found handler: org.openqa.selenium.remote.server.ServicedSession#5d54be3a 15:11:43.991 INFO - Handler thread for session 976706a5ace12e22ec54d9848f21813c (chrome): Executing POST on /session/976706a5ace12e22ec54d9848f21813c/element (handler: ServicedSession) 15:11:43.992 INFO - To upstream: {"using":"id","value":"domain"} 15:11:43.992 DEBUG - sun.net.www.MessageHeader#3bf4c11110 pairs: {POST /session/976706a5ace12e22ec54d9848f21813c/element HTTP/1.1: null}{User-Agent: Apache-HttpClient/4.5.3 (Java/1.8.0_151)}{Accept-Encoding: gzip,deflate}{Content-Type: application/json; charset=utf-8}{Connection: close}{Cache-Control: no-cache}{Pragma: no-cache}{Host: localhost:25846}{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}{Content-Length: 31} 15:11:43.998 DEBUG - sun.net.www.MessageHeader#4f3986fd4 pairs: {null: HTTP/1.1 200 OK}{Content-Length: 102}{Content-Type: application/json; charset=utf-8}{Connection: close} 15:11:43.998 INFO - To downstream: {"sessionId":"976706a5ace12e22ec54d9848f21813c","status":0,"value":{"ELEMENT":"0.8306467617329649-1"}} 15:11:44.002 INFO - Found handler: org.openqa.selenium.remote.server.ServicedSession#5d54be3a 15:11:44.002 INFO - Handler thread for session 976706a5ace12e22ec54d9848f21813c (chrome): Executing POST on /session/976706a5ace12e22ec54d9848f21813c/element/0.8306467617329649-1/value (handler: ServicedSession) 15:11:44.003 INFO - To upstream: {"id":"0.8306467617329649-1","value":["cosmotesting"]} 15:11:44.003 DEBUG - sun.net.www.MessageHeader#1eb8ea9e10 pairs: {POST /session/976706a5ace12e22ec54d9848f21813c/element/0.8306467617329649-1/value HTTP/1.1: null}{User-Agent: Apache-HttpClient/4.5.3 (Java/1.8.0_151)}{Accept-Encoding: gzip,deflate}{Content-Type: application/json; charset=utf-8}{Connection: close}{Cache-Control: no-cache}{Pragma: no-cache}{Host: localhost:25846}{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}{Content-Length: 54} 15:11:44.032 DEBUG - sun.net.www.MessageHeader#65f4e5f54 pairs: {null: HTTP/1.1 200 OK}{Content-Length: 72}{Content-Type: application/json; charset=utf-8}{Connection: close} 15:11:44.032 INFO - To downstream: {"sessionId":"976706a5ace12e22ec54d9848f21813c","status":0,"value":null} 15:11:44.036 INFO - Found handler: org.openqa.selenium.remote.server.ServicedSession#5d54be3a 15:11:44.036 INFO - Handler thread for session 976706a5ace12e22ec54d9848f21813c (chrome): Executing POST on /session/976706a5ace12e22ec54d9848f21813c/element (handler: ServicedSession) 15:11:44.036 INFO - To upstream: {"using":"id","value":"submit_team_domain"} 15:11:44.036 DEBUG - sun.net.www.MessageHeader#78955c1310 pairs: {POST /session/976706a5ace12e22ec54d9848f21813c/element HTTP/1.1: null}{User-Agent: Apache-HttpClient/4.5.3 (Java/1.8.0_151)}{Accept-Encoding: gzip,deflate}{Content-Type: application/json; charset=utf-8}{Connection: close}{Cache-Control: no-cache}{Pragma: no-cache}{Host: localhost:25846}{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}{Content-Length: 43} 15:11:44.050 DEBUG - sun.net.www.MessageHeader#7b1823924 pairs: {null: HTTP/1.1 200 OK}{Content-Length: 102}{Content-Type: application/json; charset=utf-8}{Connection: close} 15:11:44.050 INFO - To downstream: {"sessionId":"976706a5ace12e22ec54d9848f21813c","status":0,"value":{"ELEMENT":"0.8306467617329649-2"}} 15:11:44.054 INFO - Found handler: org.openqa.selenium.remote.server.ServicedSession#5d54be3a 15:11:44.054 INFO - Handler thread for session 976706a5ace12e22ec54d9848f21813c (chrome): Executing POST on /session/976706a5ace12e22ec54d9848f21813c/element/0.8306467617329649-2/click (handler: ServicedSession) 15:11:44.055 INFO - To upstream: {"id":"0.8306467617329649-2"} 15:11:44.055 DEBUG - sun.net.www.MessageHeader#22adda7510 pairs: {POST /session/976706a5ace12e22ec54d9848f21813c/element/0.8306467617329649-2/click HTTP/1.1: null}{User-Agent: Apache-HttpClient/4.5.3 (Java/1.8.0_151)}{Accept-Encoding: gzip,deflate}{Content-Type: application/json; charset=utf-8}{Connection: close}{Cache-Control: no-cache}{Pragma: no-cache}{Host: localhost:25846}{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}{Content-Length: 29}
Rails session gets destroy whenever model destroy link is clicked
If I click destroy on any record for my 3 models models, the user gets logged out. I'm using Devise and Ominauth. #This logs out a user def destroy #rating = Rating.find(params[:id]) #rating.destroy end Started POST "/ratings/29" for 192.168.1.103 at 2011-02-26 20:11:45 +0000 Processing by RatingsController#destroy as HTML Parameters: {"id"=>"29"} User Load (0.5ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1 Rating Load (0.3ms) SELECT `ratings`.* FROM `ratings` WHERE `ratings`.`id` = 29 LIMIT 1 SQL (0.0ms) BEGIN AREL (0.5ms) DELETE FROM `ratings` WHERE `ratings`.`id` = 29 SQL (2.7ms) COMMIT Request Parameters: None Show session dump session_id: "16a92c418fdfa8966b60b09e76346443" Show env dump GATEWAY_INTERFACE: "CGI/1.1" HTTP_ACCEPT: "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5" HTTP_ACCEPT_CHARSET: "ISO-8859-1,utf-8;q=0.7,*;q=0.3" HTTP_ACCEPT_ENCODING: "gzip,deflate,sdch" HTTP_ACCEPT_LANGUAGE: "en-US,en;q=0.8" HTTP_CACHE_CONTROL: "max-age=0" HTTP_CONNECTION: "keep-alive" HTTP_COOKIE: "_traitly_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRiIlMTk5NDExYjNjMWMzY2U1NWIwZDNjYjg2Y2FiMGNiNzY%3D--4c140502f8a075f61742fdf11e6fc7100722ca14" HTTP_HOST: "192.168.1.105:3000" HTTP_IF_NONE_MATCH: "\"2d7f4ba60c47e0cf39f1361e2274fa89\"" HTTP_REFERER: "http://192.168.1.105:3000/subjects" HTTP_USER_AGENT: "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.82 Safari/534.16" HTTP_VERSION: "HTTP/1.1" PATH_INFO: "/subjects" QUERY_STRING: "" REMOTE_ADDR: "192.168.1.103" REMOTE_HOST: "192.168.1.103" REQUEST_METHOD: "GET" REQUEST_PATH: "/" REQUEST_URI: "http://192.168.1.105:3000/subjects" SCRIPT_NAME: "" SERVER_NAME: "192.168.1.105" SERVER_PORT: "3000" SERVER_PROTOCOL: "HTTP/1.1" SERVER_SOFTWARE: "WEBrick/1.3.1 (Ruby/1.9.2/2010-12-25)" action_controller.instance: #<SubjectsController:0x90ecc1c #action_has_layout=true, #view_context_class=nil, #_headers={"Content-Type"=>"text/html"}, #_status=200, #_response=#<ActionDispatch::Response:0x90ecb68 ......Too long - had to cut it off action_dispatch.cookies: {"_traitly_session"=>"BAh7BkkiD3Nlc3Npb25faWQGOgZFRiIlMTk5NDExYjNjMWMzY2U1NWIwZDNjYjg2Y2FiMGNiNzY=--4c140502f8a075f61742fdf11e6fc7100722ca14"} action_dispatch.parameter_filter: [:password, :password, :password_confirmation] action_dispatch.remote_ip: 192.168.1.103 action_dispatch.request.content_type: nil action_dispatch.request.formats: [text/html] action_dispatch.request.parameters: {"action"=>"index", "controller"=>"subjects"} action_dispatch.request.path_parameters: {:action=>"index", :controller=>"subjects"} action_dispatch.request.query_parameters: {} action_dispatch.request.request_parameters: {} action_dispatch.request.unsigned_session_cookie: {"session_id"=>"199411b3c1c3ce55b0d3cb86cab0cb76"} action_dispatch.secret_token: "b3dc65e5cc9d1af31fb06160a604132f5a1f4d13edc313d74cb1bfd7e63994d429f6e8032669ea26ff4a8dab66b79f6070f8449b4a422a7862bb4307a4d84416" rack.errors: #<IO:<STDERR>> rack.input: #<StringIO:0x913578c> rack.multiprocess: false rack.multithread: false rack.request.cookie_hash: {"_traitly_session"=>"BAh7BkkiD3Nlc3Npb25faWQGOgZFRiIlMTk5NDExYjNjMWMzY2U1NWIwZDNjYjg2Y2FiMGNiNzY=--4c140502f8a075f61742fdf11e6fc7100722ca14"} rack.request.cookie_string: "_traitly_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRiIlMTk5NDExYjNjMWMzY2U1NWIwZDNjYjg2Y2FiMGNiNzY%3D--4c140502f8a075f61742fdf11e6fc7100722ca14" rack.request.query_hash: {} rack.request.query_string: "" rack.run_once: false rack.session: {"session_id"=>"199411b3c1c3ce55b0d3cb86cab0cb76"} rack.session.options: {:path=>"/", :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true, :id=>"199411b3c1c3ce55b0d3cb86cab0cb76"} rack.url_scheme: "http" rack.version: [1, 1] warden: #<Warden::Proxy:0x9133bf8 #winning_strategies={}, #users={:user=>nil}, #env={"GATEWAY_INTERFACE"=>"CGI/1.1", "PATH_INFO"=>"/subjects", "QUERY_STRING"=>"", "REMOTE_ADDR"=>"192.168.1.103", "REMOTE_HOST"=>"192.168.1.103", "REQUEST_METHOD"=>"GET", "REQUEST_URI"=>"http://192.168.1.105:3000/subjects", "SCRIPT_NAME"=>"", "SERVER_NAME"=>"192.168.1.105", "SERVER_PORT"=>"3000", "SERVER_PROTOCOL"=>"HTTP/1.1", "SERVER_SOFTWARE"=>"WEBrick/1.3.1 (Ruby/1.9.2/2010-12-25)", "HTTP_HOST"=>"192.168.1.105:3000", "HTTP_CONNECTION"=>"keep-alive", "HTTP_REFERER"=>"http://192.168.1.105:3000/subjects", "HTTP_CACHE_CONTROL"=>"max-age=0", "HTTP_USER_AGENT"=>"Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.82 Safari/534.16", "HTTP_ACCEPT"=>"application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5", "HTTP_ACCEPT_ENCODING"=>"gzip,deflate,sdch", "HTTP_ACCEPT_LANGUAGE"=>"en-US,en;q=0.8", "HTTP_ACCEPT_CHARSET"=>"ISO-8859-1,utf-8;q=0.7,*;q=0.3", "HTTP_COOKIE"=>"_traitly_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRiIlMTk5NDExYjNjMWMzY2U1NWIwZDNjYjg2Y2FiMGNiNzY%3D--4c140502f8a075f61742fdf11e6fc7100722ca14", "HTTP_IF_NONE_MATCH"=>"\"2d7f4ba60c47e0cf39f1361e2274fa89\"", "rack.version"=>[1, 1], "rack.input"=>#<StringIO:0x913578c>, "rack.errors"=>#<IO:<STDERR>>, "rack.multithread"=>false, "rack.multiprocess"=>false, "rack.run_once"=>false, "rack.url_scheme"=>"http", "HTTP_VERSION"=>"HTTP/1.1", "REQUEST_PATH"=>"/", "action_dispatch.parameter_filter"=>[:password, :password, :password_confirmation], "action_dispatch.secret_token"=>"b3dc65e5cc9d1af31fb06160a604132f5a1f4d13edc313d74cb1bfd7e63994d429f6e8032669ea26ff4a8dab66b79f6070f8449b4a422a7862bb4307a4d84416", "action_dispatch.remote_ip"=>192.168.1.103, "rack.session"=>{"session_id"=>"199411b3c1c3ce55b0d3cb86cab0cb76"}, "rack.session.options"=>{:path=>"/", :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true, :id=>"199411b3c1c3ce55b0d3cb86cab0cb76"}, "rack.request.cookie_string"=>"_traitly_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRiIlMTk5NDExYjNjMWMzY2U1NWIwZDNjYjg2Y2FiMGNiNzY%3D--4c140502f8a075f61742fdf11e6fc7100722ca14", "rack.request.cookie_hash"=>{"_traitly_session"=>"BAh7BkkiD3Nlc3Npb25faWQGOgZFRiIlMTk5NDExYjNjMWMzY2U1NWIwZDNjYjg2Y2FiMGNiNzY=--4c140502f8a075f61742fdf11e6fc7100722ca14"}, "action_dispatch.cookies"=>{"_traitly_session"=>"BAh7BkkiD3Nlc3Npb25faWQGOgZFRiIlMTk5NDExYjNjMWMzY2U1NWIwZDNjYjg2Y2FiMGNiNzY=--4c140502f8a075f61742fdf11e6fc7100722ca14"}, "action_dispatch.request.unsigned_session_cookie"=>{"session_id"=>"199411b3c1c3ce55b0d3cb86cab0cb76"}, "warden"=>#<Warden::Proxy:0x9133bf8 ...>, "action_dispatch.request.path_parameters"=>{:action=>"index", :controller=>"subjects"}, "action_controller.instance"=>#<SubjectsController:0x90ecc1c #action_has_layout=true, #view_context_class=nil, #_headers={"Content-Type"=>"text/html"}, #_status=200, #_response=#<ActionDispatch::Response:0x90ecb68 #writer=#<Proc:0x90ecaf0#/usr/local/rvm/gems/ruby-1.9.2-p136#traitly/gems/actionpack-3.0.4/lib/action_dispatch/http/response.rb:43 (lambda)>, #block=nil, #length=0, #header={}, #status=200, #body=[], #cookie=[], #sending_file=false, #blank=false, #cache_control={}, #etag=nil, #request=#<ActionDispatch::Request:0x90ecb7c #env={...}, #fullpath="/subjects", #request_method="GET", #filtered_parameters={"action"=>"index", "controller"=>"subjects"}, #method="GET">>, #_request=#<ActionDispatch::Request:0x90ecb7c #env={...}, #fullpath="/subjects", #request_method="GET", #filtered_parameters={"action"=>"index", "controller"=>"subjects"}, #method="GET">, #_env={...}, #lookup_context=#<ActionView::LookupContext:0x90ec4c4 #details_key=nil, #details={:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml], :formats=>[:html], :locale=>[:en, :en]}, #skip_default_locale=false, #frozen_formats=false, #view_paths=[/root/projects/traitly/app/views, /usr/local/rvm/gems/ruby-1.9.2-p136#traitly/gems/devise-1.1.7/app/views]>, #_action_name="index", #_response_body=nil, #_config={}, #current_user=nil>, "action_dispatch.request.content_type"=>nil, "action_dispatch.request.request_parameters"=>{}, "rack.request.query_string"=>"", "rack.request.query_hash"=>{}, "action_dispatch.request.query_parameters"=>{}, "action_dispatch.request.parameters"=>{"action"=>"index", "controller"=>"subjects"}, "action_dispatch.request.formats"=>[t
You're using Rails 3, which uses JavaScript to issue delete requests. Because the request isn't set up properly, your log is showing Started POST instead of the correct Started DELETE. The request will also not include the required CSRF data, and as of Rails 3.0.4 the session is silently reset instead of throwing an ActionController::InvalidAuthenticityToken error. This is why you suspect the authentication issue lies with Devise, but it is actually being triggered within Rails itself. To fix this include the following in your layout: <%= javascript_include_tag :defaults %> <%= csrf_meta_tag %> Also ensure you have an updated rails.js (which contains the JavaScript code used for delete requests). The Rails 3.0.4 upgrade notes explain the issue in more detail. If you're using the jquery rails.js replacement, you can get the updated version from here.