Logging in Users for Browser-Based Authentication

Before you can make authenticated service calls, users must grant your application permission to make service calls on their behalf. The user must leave your site, go to a Yahoo! login screen, and return with a token. You will use this token to retrieve the user's credentials so that you can make authenticated service calls.

This page explains how to redirect the user to a Yahoo! login page so that you can store their token. It contains these sections:

Constructing the Login URL

To start the login process, redirect the user to the URL https://api.login.yahoo.com/WSLogin/V1/wslogin with these parameters:

Field Description
appid The application ID, which identifies the developer and the application. Obtained during initial application registration.
appdata An optional url-encoded string with a maximum length of 100 characters. The Yahoo! login server returns this data to your endpoint URL without evaluating it. You can use this data for storing session data, or for redirecting your user to another URL once they return from login. If you do not need to pass data back to your own application, leave this parameter out.
send_userhash If this optional parameter equals '1', the Yahoo! login server includes an unique identifier for a particular user in your endpoint URL. With the userhash you can identify a returning user or even build an application that requires sign in without having to build the authentication part yourself. The identifier is bound to a specific appid.
ts The timestamp in seconds as measured from Jan 1, 1970 GMT. To make sure that your clock is in sync with Yahoo! login servers, use the Network Time Protocol Daemon (ntpd). We allow +/- 5 minutes of "slack" in the timestamp.
sig

An hexadecimal md5 hash of a particular relative URL:

  • The relative login path (/WSLogin/V1/wslogin), plus
  • Your application ID (?appid=id), plus
  • Optional data to be consumed by your application (&appdata=data), if any, plus
  • The timestamp (&ts=seconds), plus
  • Your shared secret (secret).

Generating the Signature

The most complex parameter is the signature sig. The signature verifies that the request came from your application and helps prevent replay attacks.

Although constructing the signature might seem daunting, all the components are easy to obtain. The basic algorithm for generating the signature and the URL is:

$appid = "i%3DB%26p%3DUw70JGIdHWVRbpqYItcMw--";  // my application ID, obtained at registration 
$appdata = "foobar";                             // my optional, arbitrary url-encoded data 
$ts = time();                                    // seconds since Jan 1, 1970 GMT
$secret = "a34f389cbd135de4618eed5e23409d34450"; // my shared secret, obtained at registration 

$sig = md5( "/WSLogin/V1/wslogin?appid=$appid&appdata=$appdata&ts=$ts" . "$secret" );
$url = "https://api.login.yahoo.com/WSLogin/V1/wslogin?appid=$appid&appdata=$appdata&ts=$ts&sig=$sig";

Notes:

  • The shared secret is used to hash the URL and create the sig parameter, but it is not a query parameter itself. When hashing the URL, you append the shared secret without any sort of &secret=.
  • If you are not passing any appdata in the login request, leave this parameter out of the hash.

The following PHP function provides a general approach to signing URLs. The function takes a URL such as https://api.login.yahoo.com/WSLogin/V1/wslogin?appid=id&appdata=data, adds a timestamp parameter, and signs it with the shared secret.

function sign_url( $url, $secret ) {
  $parts = parse_url( $url );

  $ts = time();
  $relative_uri = "";
  if ( isset( $parts["path"] ) ){
    $relative_uri .= $parts["path"];
  }
  if ( isset ( $parts["query" ] ) ) {
    $relative_uri .= "?" . $parts["query"] . "&ts=$ts";
  }

  $sig = md5( $relative_uri . $secret );

  $signed_url = $parts["scheme"] . "://" .  $parts["host"] . $relative_uri . "&sig=$sig";

  return $signed_url;
}

You can reuse this function later on, when you need to sign a slightly different URL that retrieves user credentials.

Understanding the User Login Process

You must explain to your users that they will be leaving your site temporarily for a Yahoo! login screen. Please do not surprise them. Go through the login interface as a user so that you understand the user experience. Inform your users that your application cannot access their password or other sensitive information, permissions are valid for a maximum of fourteen days, and they can revoke permission at any time by visiting their Yahoo! user profile, clicking on Account Info in the upper right corner, then clicking on 'Link your account with other sites'.

  1. The URL you constructed above presents the user with a Yahoo! login screen. After the user successfully logs in to their Yahoo! account, the login system passes them to the permission screen.

  2. The permission screen displays a legal disclaimer and informs the user that your domain is asking permission to access their personal data. The screen lists the services you are requesting. Some Yahoo! services might enable you to select a limited scope, such as "read-only services" only. The screen displays the scope as well. The user must click the I Agree button to continue.

    The user can always disable your access to their account later on by visiting their Yahoo! user profile and click the "Manage Account Links" link on the right-hand sidebar. By default, authorization lasts for fourteen days.

  3. If the user agrees to grant your application access, the Yahoo! login server redirects the user to your endpoint URL. The endpoint URL is the URL you specified during application registration. When the system redirects the user to your endpoint URL, it includes your application ID, a hashed signature to verify that the redirection came from a legitimate Yahoo! server, and a new parameter called token. The token is required to fetch user credentials for subsequent web service calls.

Understanding the Response

When the user returns to your endpoint URL, the request string includes these parameters:

Field Description
appid The application ID, which identifies the developer and the application. Obtained during initial application registration.
appdata An optional url-encoded string with a maximum length of 100 characters. This is the data you passed in during the original login call.
userhash Unique identifier for a particular user that is bound to a specific appid
ts The timestamp in seconds as measured from Jan 1, 1970 GMT. To make sure that your clock is in sync with Yahoo! login servers, use the Network Time Protocol Daemon (ntpd).
token A string that represents the user's willingness to allow your application to access their personal data. The token lasts 14 days. You will use the token to retrieve the user credentials, which enable you to make authenticated service calls.
sig An md5 hash of the relative path to your endpoint URL, all associated parameters, (appid, appdata, ts, and token), and your shared secret. You should use the signature to verify that the request came from a legitimate Yahoo! login server.

The most important returned parameter is the token. Your endpoint URL should provide some logic for retrieving the token from the URL and storing it for future use.

The user's token lasts for fourteen days. Although the token doesn't directly authenticate web service calls, it retrieves the user's credentials, which are the components that actually provide authentication. User credentials expire after one hour, but you can use the same token to keep fetching new user credentials. For more information, refer to Making Authenticated Service Calls.

The sig parameter enables you to verify that the response actually came came from Yahoo! login servers. Verifying the signature reduces your application's vulnerability to spoofing attacks. The Yahoo! login server generates its signature using the same algorithm that your application originally used to generate the signature for the user login URL.

The following PHP function uses the signature to verify the validity of the Yahoo! server's response.

function sig_validate( $secret ) {
  $ts  = $_GET["ts"];    // the current unix time
  $sig = $_GET["sig"];   // the signature of the request
  $relative_url = getenv( 'REQUEST_URI' );
  $match = array();

  // The signature is a 32 character hex string, and is the last
  // parameter at the end of the request.
  $match_rv = preg_match(  "/^(.+)&sig=(\w{32})$/", $relative_url, $match);

  if ( $match_rv == 1 ) {
    if ($match[2] != $sig ) {
      $rv = array( "status" => false,
        "error"  =>"Duplicate sig parameters passed?: $sig, " . $match[2] );
      return $rv;
    }
  }
  else {
    $rv = array( "status" => false,
       "error"  =>"Missing or invalid sig parameter" );
    return $rv;
  }

  // at this point, the url looks valid, and the sig was parsed from the url
  $relative_url_without_sig = $match[1];

  // Check that the ts parameter is within 600 seconds of the current time
  $current_time = time();
  $clock_skew  = abs($current_time - $ts);
  if ( $clock_skew >= 600 ) {
    $rv = array( "status" => false,
      "error"  => "invalid timestamp: clock_skew is $clock_skew seconds" );
    return $rv;
  }

  // now calculate the signature, and verify that the resulting signature
  // equals what was passed to us
  $sig_input = $relative_url_without_sig . $secret;
  $calculated_sig = md5($sig_input);
  if ( $calculated_sig == $sig ) {
    $rv = array( "status"=> true );
  }
  else {
    $rv = array( "status" => false,
      "error"  => "calculated_sig $calculated_sig does not match sig parameter $sig" );
  }
  return $rv;
}

Support & Community

Browser-Based Authentication and related topics are discussed on the ydn-auth mailing list.

Where to Go from Here

Making Authenticated Calls explains how to use the token to retrieve the user's credentials, which in turn enable you to make authenticated web service calls.

Ready to get started?

By applying for an Application ID for this service, you hereby agree to the Terms of Use

Yahoo Groups Discussions