Signing users in

89 out of 130 rated this helpful - Rate this topic

Before your app can work with a user's info, the user must be signed in to their Microsoft account. Typically, you do this is by adding sign-in functionality to your app in the form of a button or a hyperlink. After the user's Microsoft account has been verified, the app receives an access token. This access token confirms that the user successfully signed in and it specifies which parts of the user's info your app can work with and for how long.

The Live Connect APIs support several different ways to help you add sign-in functionality to your app. Windows Store apps use the sign-in features provided by Windows 8 and other types of apps can use the sign-in UI provided by the Live Connect APIs.

The sign-in process consists of the following steps:

  • Initialize the Live Connect APIs
  • Allow the user to sign-in to their Microsoft account, if they haven't already signed in
  • Get the session info after the user sign's in

Implementing the sign-in functionality is described for the following programming languages.

To get the most benefit from the code examples in this topic, refer to the context of the larger code samples in Working with the code examples.

Design tip

When you implement the sign-in functionality for your app, we strongly recommend that you use the Live Connect APIs to manage session state. For example, use the Live Connect APIs to determine when to change the Live Connect sign-in control's text between "sign in" and "sign out", maintain custom user states, and manage access and refresh tokens. If you write custom code to manage session-state logic, that code could cause problems by creating inconsistencies with the session state that is managed by the Live Connect APIs.

Signing a user in with JavaScript and HTML for Windows Store apps

The Live Connect APIs provide two functions that you can use to sign users in from your app by using JavaScript.

  • WL.login

    Adds sign-in functionality to any HTML element.

  • WL.ui

    Displays a sign-in button in your app.

Initialize the Live Connect APIs

Initialize the Live Connect APIs by subscribing to the auth.login event and calling WL.init when the page loads. Calling WL.init with the wl.signin scope enables single sign-on and the sign-in UI.

To use this example in your app, replace APP_CLIENT_ID with your app's client ID, and REDIRECT_URL with your app's redirect URL.

Note  Windows Store apps using JavaScript don't need to specify the client_id, redirect_uri, and response_type parameters in the call to WL.init.


WL.Event.subscribe("auth.login", onLogin);



WL.init({
    client_id: APP_CLIENT_ID,
    redirect_uri: REDIRECT_URL,
    scope: "wl.signin", 
    response_type: "token"
});


Sign in using WL.login

In Windows 8, your Windows Store apps using JavaScript should use the WL.login function to display the sign-in UI provided by Windows.

For all other types of apps, WL.login is ideal for situations where you need to provide a richer sign-in experience than the default UI provides, such as when the user must provide additional confirmation or consent for your app to work with the user's info.

When you use WL.login, you must specify the scopes and permissions that your app requires. In this example, the custom signInUser function calls WL.login to sign the user in with the wl.signin scope. The custom signInUser function is called when the user clicks the accompanying HTML button control.

(In this case, the results of the sign-in are handled by a custom onLoginComplete function, which is shown later in this topic.)


function signInUser() {
    WL.login({
        scope: "wl.signin"
    }, onLoginComplete);
}

document.write("<button onclick='signInUser()'>" +
    "Sign In</button>");


Sign in using WL.ui

If you want to follow a controls-based approach to signing users in and you're not writing a Windows Store app, we recommend that you use the WL.ui function to create a Live Connect sign-in control. With this control, you define the type of UI element you want to create.

To add a sign-in control to your app, create a container element, such as a <div> tag, with the id attribute set to signin, like this.


<div id="signin"></div>


Now you can call WL.ui to create the sign-in control. When this code runs, it adds a sign-in button to the <div> tag that has the id attribute of signin.

After the user clicks the sign-in button and successfully signs in, Live Connect asks the user to okay, or consent to, the wl.signin scope.


WL.ui({
    name: "signin",
    element: "signin"
});


In general, we recommend that you include the sign-in control as part of your initialization code.

For the sign-in coding patterns that are appropriate for Windows Store apps using JavaScript, see Guidelines for the Microsoft account sign-in experience.

Getting session info and handling events

Many of the functions in the Live Connect APIs support an optional callback parameter that your JavaScript app can use to control what happens after a call finishes.

You can also use an event handler to detect changes in user status. To handle events from the Live Connect APIs, call WL.Event.subscribe. In this example, the code subscribes to the auth.login event, which is fired after the user signs in. After the code in this example runs and the user signs in, the onLogin function is called.


WL.Event.subscribe("auth.login", onLogin);


The onLogin function in this example displays the "Signed in" message.


function onLogin() {
    document.getElementById("infoLabel").innerText = "Signed in.";
}


Another common event that an app might track is auth.sessionChange. This event is fired when an aspect of the sign-in session changes, such as when the user consents to a new scope.

This code subscribes to the auth.sessionChange event so that the onSessionChange function is called when an aspect of the user's session changes.


WL.Event.subscribe("auth.sessionChange", onSessionChange);


The onSessionChange function calls WL.getSession to get a session object for the user. The session object contains information such as the user ID, access token, and the scopes to which the user has consented.


function onSessionChange() {
    var session = WL.getSession();
    if (session) {
    document.getElementById("infoLabel").innerText =
        "Something about the session changed.";
    }
    else {
        document.getElementById("infoLabel").innerText =
            "Signed out or session error.";
    }
}


Top

Signing a user in with C# for Windows Store apps and Windows Phone apps

Windows Store apps should use the sign-in controls provided by Windows 8. For more info about the Windows 8 sign-in experience, see Guidelines for the Microsoft account sign-in experience.

Windows Phone apps using C# can use the sign-in control provided by the Live Connect APIs.

You can use the Live Connect sign-in control in C#.

Initialize the Live Connect APIs

Windows Store apps using C# and Windows Phone apps using C# initialize the Live Connect APIs when the app starts.

Sign in with the sign-in control

As noted previously, Windows Store apps should use the sign-in controls provided by Windows 8. For more info about the Windows 8 sign-in experience, see Guidelines for the Microsoft account sign-in experience.

Your Windows Phone app using C# can add the sign-in control provided by the Live Connect APIs by adding the control to the app's Extensible Application Markup Language (XAML). The example at the end of this section shows this XAML code.

The Scopes property must be set for Windows Phone apps to indicate the scopes and permissions required. Also for Windows Phone apps, you must set the SessionChanged property to the method that handles that event, and set the ClientId property to the app's client ID.

The sign-in control has other properties that you can set to customize your app's appearance.

  • Branding

    Specifies the logo to display on the sign-in button. The BrandingType enumeration describes the possible values for this property.

  • TextType

    Specifies the text to display on the sign-in button. The ButtonTextType enumeration describes the possible values for this property.

If you don't define these properties, the sign-in button will display the Windows brand logo with the text "Sign in".

Here's what the XAML code might look like for a Windows Phone app. The default page-level attributes are omitted from this example for clarity. If you use this code in your own app, replace CLIENT_ID with your app's client ID.

<phone:PhoneApplicationPage
    ...
    xmlns:my="clr-namespace:Microsoft.Live.Controls;assembly=Microsoft.Live.Controls">
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <my:SignInButton Name="btnLogin" ClientId="CLIENT_ID" Scopes="wl.signin wl.basic" Branding="Windows" TextType="SignIn" SessionChanged="btnLogin_SessionChanged" HorizontalAlignment="Left" VerticalAlignment="Top" />
        <TextBlock Height="32" HorizontalAlignment="Left" Margin="12,78,0,0" Name="infoTextBlock" Text="" VerticalAlignment="Top" Width="419" />
    </Grid>
</phone:PhoneApplicationPage>

Building a customized sign-in experience

If your app needs a customized sign-in experience, your app can prompt the user to sign in without using the Live Connect sign-in control. Likewise, after the user has signed in, you can prompt user to grant access to additional scopes when your app needs them.

One way to do this is to create a button control, and then call the following code in the button control's click event handler.

[C# for Windows Store apps and Windows Phone apps]


private async void btnMoreScopes_Click(object sender, RoutedEventArgs e)
{
    try
    {
        LiveAuthClient auth = new LiveAuthClient();
        LiveLoginResult loginResult = await auth.LoginAsync(new string[] { "wl.basic" });
        if (loginResult.Status == LiveConnectSessionStatus.Connected)
        {
            this.infoTextBlock.Text = "Signed in.";
        }
    }
    catch (LiveAuthException exception)
    {
        this.infoTextBlock.Text = "Error signing in: " + exception.Message;
    }
}


Here's what the code does:

  1. Initializes an instance of the LiveAuthClient.
  2. Calls the LoginAsync method for the instance of LiveAuthClient, specifying the requested scopes.
  3. Verifies whether the result of the LoginAsync method call is established and connected. If so, the code sets the instance of a LiveConnectSession variable. It also initializes an instance of the LiveConnectClient class for the connected client's session.

Get session info

This example shows the custom method that handles the sign-in control's SessionChanged event.


private void btnLogin_SessionChanged(object sender, LiveConnectSessionChangedEventArgs e)
{
    if (e.Status == LiveConnectSessionStatus.Connected)
    {
        session = e.Session;
        client = new LiveConnectClient(session);
        infoTextBlock.Text = "Signed in.";
    }
    else
    {
        infoTextBlock.Text = "Not signed in.";
        client = null;
    }
}


Here's what the code does:

  1. Checks to see whether the instance of the LiveConnectSessionChangedEventArgs session (represented here by the variable e) exists and is connected successfully.
  2. If so, sets the instance of LiveConnectSession (represented here by the global variable session, which was declared earlier) to the connect client's session, so that it can be reused later in code. The code also initializes an instance of the LiveConnectClient class, which represents the connected client's session (represented here by the global variable client, which was declared earlier), so that it too can be reused later in code.
  3. If the session can't be established and connected successfully, displays an error message and sets an instance of the LiveConnectClient class to null.

Localizing the sign-in control for Windows Phone apps

To display a localized version of the sign-in control and the consent page, follow these steps:

  1. Add the list of all target culture IDs to the <SupportedCultures> tag in your project file.

    This example shows what the <SupportedCultures> tag would look like if your Windows Phone app targeted French.

    
        <SupportedCultures>fr<SupportedCultures>
    
    

    For more info about using the <SupportedCultures> tag, see How to: Add Resources to a Silverlight-based Application.

    For the list of cultures that Windows Phone apps support, see Supported locales.

    For more info about globalizing your Windows Phone app, see Globalization and Localization for Windows Phone.

  2. Next, call this code before calling the Live Connect APIs, where CULTURE_ID is a supported culture ID—for example, fr for French.

    
        System.Threading.Thread.CurrentThread.CurrentUICulture = 
            new System.Globalization.CultureInfo("CULTURE_ID");
    
    

Top

Signing a user in with Objective-C for iOS

One of the ways to sign a user in with Objective-C is to do it when the app starts. Here's how.


- (void)viewDidLoad
{
    [super viewDidLoad];
    self.liveClient = [[LiveConnectClient alloc] initWithClientId:APP_CLIENT_ID 
                                                         delegate:self 
                                                        userState:@"genesis"]; 
}

- (void) authCompleted:(LiveConnectSessionStatus)status 
               session:(LiveConnectSession *)session 
             userState:(id)userState
{   
    if (session != nil) {
        self.statusLabel.text = @"You are signed in.";
    }
}

- (void) authFailed:(NSError *)error 
          userState:(id)userState
{
    // Failed. 
}


Here's what this code does:

  1. In the viewDidLoad method, initializes an instance of the LiveConnectClient interface, named liveClient. In doing so, the code specifies the app's client ID, indicates that the current instance will be handling the initialization success and failure messages, and specifies an optional, unique user-state argument (@"genesis", in this case) for easier method handling later.
  2. If the LiveConnectClient instance is successfully initialized, the authCompleted:session:userState method is called. Otherwise, the authFailed:userState method is called.
  3. If the user successfully signs in and consents, the authCompleted:session:userState method is called once again. Otherwise, the authFailed:userState method is called.

You can also prompt the user to sign in after the app starts. One way to do this is to create a button control and then call the sign-in code in the button control's click-event handler, like this.


- (IBAction)onClickSignInButton:(id)sender {
    if (self.liveClient.session == nil)
    {
        [self.liveClient login:self 
                        scopes:[NSArray arrayWithObjects:@"wl.signin", nil ] 
                      delegate:self 
                     userState:@"signin"];
    }
    else
    {
        [self.liveClient logoutWithDelegate:self 
                                  userState:@"signout"];
    }
}

- (void) authCompleted:(LiveConnectSessionStatus)status 
               session:(LiveConnectSession *)session 
             userState:(id)userState
{   
    [self updateButtons];
    if (session != nil) {
        self.statusLabel.text = @"You are signed in.";
    }
}

- (void) authFailed:(NSError *)error userState:(id)userState
{
    // Failed. 
}

- (void) updateButtons {
    LiveConnectSession *session = self.liveClient.session;
    NSString *signInButtonText = (session == nil)? @"Sign in": @"Sign out";
    [self.signInButton setTitle:signInButtonText 
                       forState:UIControlStateNormal];
}


Here's what the code does:

  1. Uses the login:scopes:delegate:userState method of the LiveConnectClient instance. The code specifies the scopes to use, indicates that the current instance will be handling the authorization success and failure messages, and specifies a unique user-state argument (@"signin", in this case) for easier method handling later.
  2. If the user successfully signs in and consents, the authCompleted:session:userState method is called. Otherwise, the authFailed:userState method is called.

Note   This code's parent interface must implement the LiveAuthDelegate interface before calling the authCompleted and authFailed methods.

Signing a user in with Java for Android

One of the ways to sign a user in with Java is to do it when the app starts. Here's how.


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    this.resultTextView = (TextView)findViewById(R.id.resultTextView);
    this.auth = new LiveAuthClient(this, MyConstants.APP_CLIENT_ID);
}

@Override
protected void onStart() {
    super.onStart();
    Iterable<String> scopes = Arrays.asList("wl.signin", "wl.basic");
    this.auth.login(scopes, this);
}

public void onAuthComplete(LiveStatus status, LiveConnectSession session, Object userState) {
    if(status == LiveStatus.CONNECTED) {
        this.resultTextView.setText("Signed in.");
        client = new LiveConnectClient(session);
    }
    else {
        this.resultTextView.setText("Not signed in.");
        client = null;
    }        
}

public void onAuthError(LiveAuthException exception, Object userState) {
    this.resultTextView.setText("Error signing in: " + exception.getMessage());        
    client = null;        
}


Here's what this code does:

  1. In the app's main Activity class, in the onCreate method, initializes an instance of the LiveAuthClient class, specifying the app's client ID.
  2. In the app's main Activity class, in the onStart method, calls the login method for the instance of LiveAuthClient, specifying the requested scopes.
  3. If the connected client's session is established and connected, calls the onAuthComplete method. That method initializes an instance of the LiveConnectClient class for the connected client's session (represented here by the global variable client, which was declared earlier), so that it also can be reused later in code.
  4. If the connected client's session cannot be established and connected, however, calls the onAuthError method and displays an error message.

After an initial sign-in, you can prompt the signed-in user to okay additional scopes that your app needs. One way to do this is to create a button control and then call the sign-in code in the button control's click-event handler, like this.


public void moreScopes() {        
    auth.login(this, Arrays.asList(new String[] { "wl.basic" }), new LiveAuthListener() {
        public void onAuthComplete(LiveStatus status, LiveConnectSession session, Object userState) {
            if (status == LiveStatus.CONNECTED) {
                resultTextView.setText("Signed in.");
                client = new LiveConnectClient(session);
            } else {
                resultTextView.setText("Not signed in.");
                client = null;
            }
        }
        public void onAuthError(LiveAuthException exception, Object userState) {
            resultTextView.setText("Error signing in: " + exception.getMessage());        
            client = null;
        }
    });            
}


Here's what the code does:

  1. Defines a list of additional scopes.
  2. Calls the instance of the initialize method of the LiveAuthClient class (represented here by the global variable auth, which was declared earlier) with the list of additional scopes and a new instance of a LiveAuthListener class.
  3. If the connected client's session is established and connected, calls the onAuthComplete method. That method initializes an instance of the LiveConnectClient class for the connected client's session (represented here by the global variable client, which was declared earlier), so that it also can be reused later in code.
  4. If the connected client's session cannot be established and connected, however, calls the onAuthError method and displays an error message.

Signing a user in with REST

If your app can't use any of the approaches previously described in this topic, we provide a Representational State Transfer (REST) implementation. To use it, your app must initiate the sign-in process by contacting the Live Connect authorization web service. To do this, make the following call from a web browser or a web-browser control.


GET https://login.live.com/oauth20_authorize.srf?client_id=CLIENT_ID&scope=SCOPES&response_type=RESPONSE_TYPE&redirect_uri=REDIRECT_URL

Note  

Mobile apps should append &display=touch to the authorization service URL.

In this code, replace the following values:

  • Replace CLIENT_ID with your app's client ID.
  • Replace SCOPES with the list of scopes to be requested. To specify more than one scope, separate each scope with the escape code for a space, for example, wl.signin%20wl.basic. (For more info about scopes, see Obtaining user consent.)
  • Replace RESPONSE_TYPE with the specific type of response. If you're using the implicit grant flow, use token to specify an access token to be returned. If you're using the authorization code grant flow, use code to specify an authorization code to be returned.
  • If you're using the implicit grant flow, replace REDIRECT_URL with https://login.live.com/oauth20_desktop.srf. If you're using the authorization code grant flow, replace REDIRECT_URL with the URL to your callback web page. If you specified a redirect domain when you created your client ID (like http://www.contoso.com), the redirect domain portion of the URL must be the same as the one that you specified when your client ID was created. In any case, the URL must use URL escape codes in this REST call, such as %20 for spaces, %3A for colons, and %2F for forward slashes.

    Note   For details about the implicit grant flow and the authorization code grant flow, see OAuth 2.0.

When Live Connect receives this call, it checks to see whether the user is already signed in. If not, the user is prompted to provide his or her Microsoft account credentials.

After the user successfully signs in and consents to the requested scopes, the Live Connect authorization web service uses the redirect domain to return the user to your app. If you're using the implicit grant flow, you'll see this.

https://login.live.com/oauth20_desktop.srf#access_token=ACCESS_TOKEN&token_type=bearer&authentication_token=AUTHENTICATION_TOKEN&expires_in=3600&scope=SCOPES

You use the returned access token (represented here as ACCESS_TOKEN) to work with a user's info. To see how, skip to the end of this section.

However, if you're using the authorization code grant flow, different info is returned, and you'll need to make one more call. Here's what's returned.

http://www.contoso.com/Callback.htm?code=AUTHORIZATION_CODE

If you're using the authorization code grant flow, you use the returned authorization code (represented here as AUTHORIZATION_CODE) to make another call to obtain an access token. Here's that call.

POST https://login.live.com/oauth20_token.srf

Content-Type: application/x-www-form-urlencoded

client_id=CLIENT_ID&redirect_uri=REDIRECT_URL&client_secret=CLIENT_SECRET&code=AUTHORIZATION_CODE&grant_type=authorization_code

In the body, replace these:

  • Replace CLIENT_ID with your app's client ID.
  • Replace REDIRECT_URL with the URL to your callback webpage. This URL must be the same as the URL that you specified when you requested an authorization code. The URL must use URL escape codes, such as %20 for spaces, %3A for colons, and %2F for forward slashes.
  • Replace CLIENT_SECRET with the client secret that you received when your client ID was created.
  • Replace AUTHORIZATION_CODE with the authorization code that was returned on the initial call.

If this second call is successful, the response from the Live Connect authorization web service contains a JavaScript Object Notation (JSON)-formatted object that includes the access token. The access token is contained in a JSON-formatted object that looks like this, where ACCESS_TOKEN represents the actual access token, and SCOPES represents the actual scopes.

{
    "access_token": "ACCESS_TOKEN",
    "expires_in": 3600,
    "scope":"SCOPES",
    "token_type":"bearer"
}

At this point, you can use REST calls to work with the signed-in user's info. For each request, you must append an access_token parameter that contains the access token. Note that the access token is valid for only the number of seconds that are specified in the expires_in value. Here, REST_PATH represents the actual target REST path (like me), and ACCESS_TOKEN represents the actual access token.

https://apis.live.net/v5.0/REST_PATH?access_token=ACCESS_TOKEN

For info about using this implementation in a server-side website or script, see Server-side scenarios.

Top

Next steps

Now that you understand how to sign users in by using the Live Connect APIs, learn more about:

Top

 

 

Did you find this helpful?
(1500 characters remaining)
Thank you for your feedback
Show:
© 2014 Microsoft. All rights reserved.