Logging Into an Online Account

In a previous post, we learned how to associate a channel with an online service using rendezvous style linking. In this post, we’ll associate a channel with an online service by logging in directly with a username and password. Any time you send sensitive information over the internet, it’s important to make sure that information is secure. Be sure you take the necessary precautions to protect your users’ data.

We’re going to ask the user to enter two chunks of information, a username and a password. We will be using the roKeyboardScreen component for both of these tasks, so the first thing we need is a reusable function that presents a roKeyboardScreen and returns whatever string the user types into it.

function ShowKeyboardScreen(prompt = "", secure = false)
  result = ""

  ' create a roKeyboardScreen and assign a message port to it
  port = CreateObject("roMessagePort")
  screen = CreateObject("roKeyboardScreen")
  screen.SetMessagePort(port)

  ' display a short string telling the user what they need to enter
  screen.SetDisplayText(prompt)

  ' add some buttons
  screen.AddButton(1, "Okay")
  screen.AddButton(2, "Cancel")

  ' if secure is true, the typed text will be obscured on the screen
  ' this is useful when the user is entering a password
  screen.SetSecureText(secure)

  ' display our keyboard screen
  screen.Show()

  while true
    ' wait for an event from the screen
    msg = wait(0, port)

    if type(msg) = "roKeyboardScreenEvent" then
      if msg.isScreenClosed() then
        exit while
      else if msg.isButtonPressed()
        if msg.GetIndex() = 1
          ' the user pressed the Okay button
          ' close the screen and return the text they entered
          result = screen.GetText()
          exit while
        else if msg.GetIndex() = 2
          ' the user pressed the Cancel button
          ' close the screen and return an empty string
          result = ""
          exit while
        end if
      end if
    end if
  end while

  screen.Close()
  return result
end function

Now we can use our keyboard screen to solicit information from the user. Notice that the second call to ShowKeyboardScreen() has two arguments. Passing a true value as the second argument will cause the text to be obscured on the screen as the user is typing their password.

username = ShowKeyboardScreen("Enter your username")
if username <> ""
  ' only prompt the user for a password if they entered a username
  password = ShowKeyboardScreen("Enter your username", true)
end if

Once you have the user’s credentials, it is safe to store them in the device registry because all data stored in the registry is encrypted, Access to registry data is tied to the developer key used to package your channel, so make sure future updates to your channel are packaged with the same key. Otherwise your channel will lose access to any data stored in the registry and your users will have to go through the login process again. It is also important to protect the key and its associated password appropriately.

Now you can use the credentials to make an API call to your cloud service and authenticate the channel to the user’s account. Because we’re sending sensitive data, we’ll use SSL to encrypt the data when making the transfer. For purposes of this example, we’ll assume that the API will return a chunk of XML containing a token that should be used when making subsequent API calls.

if username <> "" and password <> ""
  ' the user entered both a username and a password
  ' store them in the registry for logging in during future sessions
  sec = CreateObject("roRegistrySection", "mySection")
  sec.Write("username", username)
  sec.Write("password", password)
  sec.Flush()

  ' and now let's try logging in
  xfer = CreateObject("roURLTransfer")
  ' setup the transfer for SSL
  xfer.SetCertificatesFile("common:/certs/ca-bundle.crt")
  xfer.InitClientCertificates()
  xfer.SetURL("https://api.example.com/login?username=" + xfer.Escape(username) + "&password=" + xfer.Escape(password))
  response = xfer.GetToString()

  ' parse the response and extract the apiToken
  xml = CreateObject("roXMLElement")
  if xml.Parse(response)
    apiToken = xml.token.GetText()
  end if
end if

Once the channel is associated with the user’s account, you can give them a personalized experience within your channel.

This entry was posted in sdk. Bookmark the permalink.
  • Alex

    I would assume you should store some server-generated hash representing a successful login, like a cookie or something. Storing a user’s plaintext password under any circumstances seems like a bad idea to me.

  • Bandal

    What if someone else gives another Roku owner the username and password? How do we check that the serial number matches the original User who registered?

  • GoodNachos

    when using this code in my channel, the entire channel exits upon hitting “submit” rather than proceed to the next sequence of code (nothing helpful in the debug window). I have the same result when pasting code from the reference manual. is there a strategy or preferred sequence to showing/closing screens that you can share when using roKeyboardScreen? thanks!

    • Richo

      Hi did you find any work around for this issue? I have the same problem.

      Richo

      • Marcelo

        All you need to do is create a background facade page before you call the authentication screems:

        ‘—– Screen Facade Background here —————
        screenFacade = CreateObject(“roPosterScreen”)
        screenFacade.show()