HTMLDialog - make a get request with Authentication header

sketchup
ui::htmldialog

#1

Hi, my question would be the following. What should i do, if i want to make a request on a URL that needs the basic auth header to give back HTML result? I’m trying to use the UI::HTMLDialog.

Thanks,
Gabor


#2

Read up on using the Ruby standard library …

http://ruby-doc.org/stdlib-2.2.4/libdoc/net/http/rdoc/Net/HTTP.html

Then you might adapt it to using the newer SketchUp API classes …

References that help …

(IETF) RFC7617 : The ‘Basic’ HTTP Authentication Scheme


#3

The HtmlDialog (which should be called HTMLDialog by Ruby naming conventions, but sadly isn’t) doesn’t have this built in. Using the Http module as Dan suggest is probably the best. Then you could use the HtmlDialog#set_html method to display the content loaded from the server in the HtmlDialog.


#4

Also note that sending user and password embedded in the URI is supported by the Ruby library, but is deprecated by the W3C.

ie, "https://Aladdin:OpenSesame@www.example.com/index.html"

So some browsers no longer support it. You’d have to check if Chromium does or not.

EDIT: URI embedded credentials looks like it was dropped from Chrome ~2012 and from Internet Explorer prior to that. There were serious security flaws in this method. So it is a good idea to use the example I give below.


#5

Here is an untested example …

ADD: You could probably drop the dialog argument and just use self within the methods (which refers to the instance itself within instance methods. (The example was adapted from some other old code examples.)

module SomeAuthor::SomePlugin

  AuthDialog = Class.new( defined?(UI::HtmlDialog) ? UI::HtmlDialog : UI::WebDialog )
  class AuthDialog

    # (IETF) RFC7617 : The ‘Basic’ HTTP Authentication Scheme
    # https://tools.ietf.org/html/rfc7617

    if self < UI::WebDialog
    
      # using the Standard Ruby Library Net::HTTP classes ...
      require 'net/http' # loads 'uri'

      def get_page(dialog, url, username, password, form)

        fail(ArgumentError, "username cannot contain a colon!",caller) if username.include?(':')

        uri = URI(url)
        req = Net::HTTP::Get.new(uri)
        req.basic_auth(username, password)
        req.set_form_data(form)

        UI.start_timer(0,false) do
          @res = Net::HTTP.start(uri.hostname, uri.port) {|http|
            http.request(req) do |response|
              dialog.set_html(response.body)
              dialog.show if !dialog.visible?
            end
          }
        end

      end
  
    else

      # using the SketchUp Ruby API HTTP classes v2017+ ...
      require 'uri'
      require 'base64'

      def get_page(dialog, url, username, password, form)

        fail(ArgumentError, "username cannot contain a colon!",caller) if username.include?(':')

        uri = URI(url)
        creds = "#{username}:#{password}"

        @req = Sketchup::Http::Request.new(uri.to_s, Sketchup::Http::GET)
        @req.headers= { 'Authorization' => 'Basic '<< Base64.encode64(creds) }
        @req.body= URI.encode_www_form(form)

        @req.start do |request, response|
          dialog.set_html(response.body)
          dialog.show if !dialog.visible?
        end

      end

    end

  end # class AuthDialog
end # module namespaces

… and a call to the method would be like …

get_page( 
  dlg, "http://www.mywebsite.com",
  'somebody', 'suchandsuch',
  'search' => 'some_query', 'lang' => Sketchup.get_locale
)

* … of course the form data fields can be whatever they need to be for the target webpage.


SendOwl License API
SendOwl License API
#6

Thank you for the answers. Yes i knew, that this was an option, i just thought maybe i’m missing something. I’m not trying to use basic auth, it’s just an authentication header with an AccessToken, so that’s not gonna be a problem. Using a standard HTTP client, is not the same as a browser as far as i know.
I’m gonna try to make it work like this, thank you again for the advice.

Maybe a follow up question if i may, what’s the advantage of using the sketchup HTTP API, instead of the Ruby std. lib?


#7

Thank you very much, for answering my question.


#8

Well you said that in the first post unless you meant “plain-Jane” instead of “Basic” … so that is what we gave answers toward. (No biggie.)

Okay, then what I did not show above was that the standard Net::HTTP library makes it really easy to set and get headers for requests and response objects. Both classes (and their subclasses) have defined shortcut [] methods. Ie …

request["Access-Token"]= "QWxhZGRpbjpPcGVuU2VzYW1l"

… or …

if response["Cache-Control"] == "no-cache" then # do something ...

Thomas of the SketchUp Extensibility Team gives a quick answer in a issue thread from last week in the official API public issue tracker …


#9

Thanks again. Yes i know i wrote that, i wasn’t trying to blame you for answering what i asked, i just realized it after, that i asked the wrong question.