Permalink
Browse files

Update Asp.Net and Php samples

- Auth endpoint changes
- Asp.net: added JsonWebToken parsing sample
- Asp.net: some code refactory
  • Loading branch information...
1 parent 91a796d commit 57ff575bc5700e75640f0e3066a15c536b5d4e29 unknown committed Apr 11, 2012
View
336 Samples/Asp.net/OAuthSample/App_Code/JsonWebToken.cs
@@ -0,0 +1,336 @@
+namespace OAuthTest
+{
+ // Reference: http://tools.ietf.org/search/draft-jones-json-web-token-00
+ //
+ // JWT is made up of 3 parts: Envelope, Claims, Signature.
+ // - Envelope - specifies the token type and signature algorithm used to produce
+ // signature segment. This is in JSON format
+ // - Claims - specifies claims made by the token. This is in JSON format
+ // - Signature - Cryptographic signature use to maintain data integrity.
+ //
+ // To produce a JWT token:
+ // 1. Create Envelope segment in JSON format
+ // 2. Create Claims segment in JSON format
+ // 3. Create signature
+ // 4. Base64url encode each part and append together separated by "."
+
+ using System;
+ using System.Collections.Generic;
+ using System.Security.Cryptography;
+ using System.Text.RegularExpressions;
+ using System.Runtime.Serialization;
+ using System.Runtime.Serialization.Json;
+ using System.Text;
+ using System.IO;
+
+ public class JsonWebToken
+ {
+ #region Helper Classes
+ [DataContract]
+ public class JsonWebTokenClaims
+ {
+
+ [DataMember(Name = "exp")]
+ private int expUnixTime
+ {
+ get;
+ set;
+ }
+
+ private DateTime? expiration = null;
+ public DateTime Expiration
+ {
+ get
+ {
+ if (this.expiration == null)
+ {
+ this.expiration = new DateTime(1970, 1, 1, 0, 0, 0).AddSeconds(expUnixTime);
+ }
+
+ return (DateTime)this.expiration;
+ }
+ }
+
+ [DataMember(Name = "iss")]
+ public string Issuer
+ {
+ get;
+ private set;
+ }
+
+ [DataMember(Name = "aud")]
+ public string Audience
+ {
+ get;
+ private set;
+ }
+
+ [DataMember(Name = "uid")]
+ public string UserId
+ {
+ get;
+ private set;
+ }
+
+ [DataMember(Name = "ver")]
+ public int Version
+ {
+ get;
+ private set;
+ }
+
+ [DataMember(Name = "urn:microsoft:appuri")]
+ public string ClientIdentifier
+ {
+ get;
+ private set;
+ }
+
+ [DataMember(Name = "urn:microsoft:appid")]
+ public string AppId
+ {
+ get;
+ private set;
+ }
+ }
+
+ [DataContract]
+ public class JsonWebTokenEnvelope
+ {
+ [DataMember(Name = "typ")]
+ public string Type
+ {
+ get;
+ private set;
+ }
+
+ [DataMember(Name = "alg")]
+ public string Algorithm
+ {
+ get;
+ private set;
+ }
+
+ [DataMember(Name = "kid")]
+ public int KeyId
+ {
+ get;
+ private set;
+ }
+ }
+ #endregion
+
+ #region Properties
+
+ private static readonly DataContractJsonSerializer ClaimsJsonSerializer = new DataContractJsonSerializer(typeof(JsonWebTokenClaims));
+ private static readonly DataContractJsonSerializer EnvelopeJsonSerializer = new DataContractJsonSerializer(typeof(JsonWebTokenEnvelope));
+ private static readonly UTF8Encoding UTF8Encoder = new UTF8Encoding(true, true);
+ private static readonly SHA256Managed SHA256Provider = new SHA256Managed();
+
+ private string claimsTokenSegment;
+ public JsonWebTokenClaims Claims
+ {
+ get;
+ private set;
+ }
+
+ private string envelopeTokenSegment;
+ public JsonWebTokenEnvelope Envelope
+ {
+ get;
+ private set;
+ }
+
+ public string Signature
+ {
+ get;
+ private set;
+ }
+
+ public bool IsExpired
+ {
+ get
+ {
+ return this.Claims.Expiration < DateTime.Now;
+ }
+ }
+
+ #endregion
+
+ #region Constructors
+ public JsonWebToken(string token, Dictionary<int, string> keyIdsKeys)
+ {
+ // Get the token segments & perform validation
+ string[] tokenSegments = this.SplitToken(token);
+
+ // Decode and deserialize the claims
+ this.claimsTokenSegment = tokenSegments[1];
+ this.Claims = this.GetClaimsFromTokenSegment(this.claimsTokenSegment);
+
+ // Decode and deserialize the envelope
+ this.envelopeTokenSegment = tokenSegments[0];
+ this.Envelope = this.GetEnvelopeFromTokenSegment(this.envelopeTokenSegment);
+
+ // Get the signature
+ this.Signature = tokenSegments[2];
+
+ // Ensure that the tokens KeyId exists in the secret keys list
+ if (!keyIdsKeys.ContainsKey(this.Envelope.KeyId))
+ {
+ throw new Exception(string.Format("Could not find key with id {0}", this.Envelope.KeyId));
+ }
+
+ // Validation
+ this.ValidateEnvelope(this.Envelope);
+ this.ValidateSignature(keyIdsKeys[this.Envelope.KeyId]);
+ }
+
+ private JsonWebToken()
+ {
+ }
+ #endregion
+
+ #region Parsing Methods
+
+ private JsonWebTokenClaims GetClaimsFromTokenSegment(string claimsTokenSegment)
+ {
+ byte[] claimsData = this.Base64UrlDecode(claimsTokenSegment);
+ using (MemoryStream memoryStream = new MemoryStream(claimsData))
+ {
+ return ClaimsJsonSerializer.ReadObject(memoryStream) as JsonWebTokenClaims;
+ }
+ }
+
+ private JsonWebTokenEnvelope GetEnvelopeFromTokenSegment(string envelopeTokenSegment)
+ {
+ byte[] envelopeData = this.Base64UrlDecode(envelopeTokenSegment);
+ using (MemoryStream memoryStream = new MemoryStream(envelopeData))
+ {
+ return EnvelopeJsonSerializer.ReadObject(memoryStream) as JsonWebTokenEnvelope;
+ }
+ }
+
+ private string[] SplitToken(string token)
+ {
+ // Expected token format: Envelope.Claims.Signature
+
+ if (string.IsNullOrEmpty(token))
+ {
+ throw new Exception("Token is empty or null.");
+ }
+
+ string[] segments = token.Split('.');
+
+ if (segments.Length != 3)
+ {
+ throw new Exception("Invalid token format. Expected Envelope.Claims.Signature");
+ }
+
+ if (string.IsNullOrEmpty(segments[0]))
+ {
+ throw new Exception("Invalid token format. Envelope must not be empty");
+ }
+
+ if (string.IsNullOrEmpty(segments[1]))
+ {
+ throw new Exception("Invalid token format. Claims must not be empty");
+ }
+
+ if (string.IsNullOrEmpty(segments[2]))
+ {
+ throw new Exception("Invalid token format. Signature must not be empty");
+ }
+
+ return segments;
+ }
+
+ #endregion
+
+ #region Validation Methods
+
+ private void ValidateEnvelope(JsonWebTokenEnvelope envelope)
+ {
+ if (envelope.Type != "JWT")
+ {
+ throw new Exception("Unsupported token type");
+ }
+
+ if (envelope.Algorithm != "HS256")
+ {
+ throw new Exception("Unsupported crypto algorithm");
+ }
+ }
+
+ private void ValidateSignature(string key)
+ {
+ // Derive signing key, Signing key = SHA256(secret + "JWTSig")
+ byte[] bytes = UTF8Encoder.GetBytes(key + "JWTSig");
+ byte[] signingKey = SHA256Provider.ComputeHash(bytes);
+
+ // To Validate:
+ //
+ // 1. Take the bytes of the UTF-8 representation of the JWT Claim
+ // Segment and calculate an HMAC SHA-256 MAC on them using the
+ // shared key.
+ //
+ // 2. Base64url encode the previously generated HMAC as defined in this
+ // document.
+ //
+ // 3. If the JWT Crypto Segment and the previously calculated value
+ // exactly match in a character by character, case sensitive
+ // comparison, then one has confirmation that the key was used to
+ // generate the HMAC on the JWT and that the contents of the JWT
+ // Claim Segment have not be tampered with.
+ //
+ // 4. If the validation fails, the token MUST be rejected.
+
+ // UFT-8 representation of the JWT envelope.claim segment
+ byte[] input = UTF8Encoder.GetBytes(this.envelopeTokenSegment + "." + this.claimsTokenSegment);
+
+ // calculate an HMAC SHA-256 MAC
+ using (HMACSHA256 hashProvider = new HMACSHA256(signingKey))
+ {
+ byte[] myHashValue = hashProvider.ComputeHash(input);
+
+ // Base64 url encode the hash
+ string base64urlEncodedHash = this.Base64UrlEncode(myHashValue);
+
+ // Now compare the two has values
+ if (base64urlEncodedHash != this.Signature)
+ {
+ throw new Exception("Signature does not match.");
+ }
+ }
+ }
+
+ #endregion
+
+ #region Base64 Encode / Decode Functions
+ // Reference: http://tools.ietf.org/search/draft-jones-json-web-token-00
+
+ public byte[] Base64UrlDecode(string encodedSegment)
+ {
+ string s = encodedSegment;
+ s = s.Replace('-', '+'); // 62nd char of encoding
+ s = s.Replace('_', '/'); // 63rd char of encoding
+ switch (s.Length % 4) // Pad with trailing '='s
+ {
+ case 0: break; // No pad chars in this case
+ case 2: s += "=="; break; // Two pad chars
+ case 3: s += "="; break; // One pad char
+ default: throw new System.Exception("Illegal base64url string");
+ }
+ return Convert.FromBase64String(s); // Standard base64 decoder
+ }
+
+ public string Base64UrlEncode(byte[] arg)
+ {
+ string s = Convert.ToBase64String(arg); // Standard base64 encoder
+ s = s.Split('=')[0]; // Remove any trailing '='s
+ s = s.Replace('+', '-'); // 62nd char of encoding
+ s = s.Replace('/', '_'); // 63rd char of encoding
+ return s;
+ }
+ #endregion
+ }
+}
View
25 Samples/Asp.net/OAuthSample/App_Code/OAuthConstants.cs
@@ -0,0 +1,25 @@
+using System;
+
+namespace OAuthTest
+{
+ public static class OAuthConstants
+ {
+ #region OAuth 2.0 standard parameters
+ public const string ClientID = "client_id";
+ public const string ClientSecret = "client_secret";
+ public const string Callback = "redirect_uri";
+ public const string ClientState = "state";
+ public const string Scope = "scope";
+ public const string Code = "code";
+ public const string AccessToken = "access_token";
+ public const string AuthenticationToken = "authentication_token";
+ public const string ExpiresIn = "expires_in";
+ public const string RefreshToken = "refresh_token";
+ public const string ResponseType = "response_type";
+ public const string GrantType = "grant_type";
+ public const string Error = "error";
+ public const string ErrorDescription = "error_description";
+ public const string Display = "display";
+ #endregion
+ }
+}
View
22 Samples/Asp.net/OAuthSample/App_Code/OAuthError.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Runtime.Serialization;
+using System.Runtime.Serialization.Json;
+
+namespace OAuthTest
+{
+ [DataContract]
+ public class OAuthError
+ {
+ public OAuthError(string code, string desc)
+ {
+ this.Code = code;
+ this.Description = desc;
+ }
+
+ [DataMember(Name = OAuthConstants.Error)]
+ public string Code { get; private set; }
+
+ [DataMember(Name = OAuthConstants.ErrorDescription)]
+ public string Description { get; private set; }
+ }
+}
View
25 Samples/Asp.net/OAuthSample/App_Code/OAuthToken.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Runtime.Serialization;
+using System.Runtime.Serialization.Json;
+
+namespace OAuthTest
+{
+ [DataContract]
+ public class OAuthToken
+ {
+ [DataMember(Name = OAuthConstants.AccessToken)]
+ public string AccessToken { get; set; }
+
+ [DataMember(Name = OAuthConstants.AuthenticationToken)]
+ public string AuthenticationToken { get; set; }
+
+ [DataMember(Name = OAuthConstants.RefreshToken)]
+ public string RefreshToken { get; set; }
+
+ [DataMember(Name = OAuthConstants.ExpiresIn)]
+ public string ExpiresIn { get; set; }
+
+ [DataMember(Name = OAuthConstants.Scope)]
+ public string Scope { get; set; }
+ }
+}
View
81 Samples/Asp.net/OAuthSample/Callback.aspx.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
+
using System.IO;
using System.Linq;
using System.Net;
@@ -11,18 +12,19 @@
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
-
+
public partial class Callback : System.Web.UI.Page
{
private const string wlCookie = "wl_auth";
// Update the following values
private const string clientId = "%CLIENT_ID%";
+
// Make sure this is identical to the redirect_uri parameter passed in WL.init() call.
private const string callback = "%REDIRECT_URI_PATH%/callback.aspx";
private const string clientSecret = "%CLIENT_SECRET%";
- private const string oauthUrl = "https://oauth.live.com/token";
+ private const string oauthUrl = "https://login.live.com/oauth20_token.srf";
protected void Page_Load(object sender, EventArgs e)
{
@@ -102,7 +104,7 @@ private static void RequestAccessToken(string postContent, out OAuthToken token,
HttpWebRequest request = WebRequest.Create(oauthUrl) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
-
+
try
{
using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
@@ -158,10 +160,15 @@ private static void HandleTokenResponse(HttpContext context, OAuthToken token, O
if (token != null)
{
+ JsonWebToken userInfo = ReadUserInfoFromAuthToken(token);
+ // The userInfo contains identifiable information about the user.
+ // You may add some logic here.
+
newCookie[OAuthConstants.AccessToken] = HttpUtility.UrlEncode(token.AccessToken);
+ newCookie[OAuthConstants.AuthenticationToken] = HttpUtility.UrlEncode(token.AuthenticationToken);
newCookie[OAuthConstants.Scope] = HttpUtility.UrlPathEncode(token.Scope);
newCookie[OAuthConstants.ExpiresIn] = HttpUtility.UrlEncode(token.ExpiresIn);
-
+
if (!string.IsNullOrEmpty(token.RefreshToken))
{
SaveRefreshToken(token.RefreshToken);
@@ -176,57 +183,23 @@ private static void HandleTokenResponse(HttpContext context, OAuthToken token, O
context.Response.Cookies.Add(newCookie);
}
- }
-
- [DataContract]
- public class OAuthToken
- {
- [DataMember(Name = OAuthConstants.AccessToken)]
- public string AccessToken { get; set; }
- [DataMember(Name = OAuthConstants.RefreshToken)]
- public string RefreshToken { get; set; }
-
- [DataMember(Name = OAuthConstants.ExpiresIn)]
- public string ExpiresIn{get; set;}
-
- [DataMember(Name = OAuthConstants.Scope)]
- public string Scope { get; set; }
- }
-
- public static class OAuthConstants
- {
- #region OAuth 2.0 standard parameters
- public const string ClientID = "client_id";
- public const string ClientSecret = "client_secret";
- public const string Callback = "redirect_uri";
- public const string ClientState = "state";
- public const string Scope = "scope";
- public const string Code = "code";
- public const string AccessToken = "access_token";
- public const string ExpiresIn = "expires_in";
- public const string RefreshToken = "refresh_token";
- public const string ResponseType = "response_type";
- public const string GrantType = "grant_type";
- public const string Error = "error";
- public const string ErrorDescription = "error_description";
- public const string Display = "display";
- #endregion
- }
-
- [DataContract]
- public class OAuthError
- {
- public OAuthError(string code, string desc)
+ private static JsonWebToken ReadUserInfoFromAuthToken(OAuthToken token)
{
- this.Code = code;
- this.Description = desc;
- }
-
- [DataMember(Name = OAuthConstants.Error)]
- public string Code { get; private set; }
+ string authenticationToken = token.AuthenticationToken;
+ Dictionary<int, string> keys = new Dictionary<int, string>();
+ keys.Add(0, clientSecret);
- [DataMember(Name = OAuthConstants.ErrorDescription)]
- public string Description { get; private set; }
- }
+ JsonWebToken jwt = null;
+ try
+ {
+ jwt = new JsonWebToken(authenticationToken, keys);
+ return jwt;
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+ }
+ }
}
View
89 Samples/Asp.net/OAuthSample/default.html
@@ -7,7 +7,7 @@
<!--
.Name
{
- font-family: Segoe UI, Verdana, Tahoma, Helvetica, Arial, sans-serif;
+ font-family: 'Segoe UI', Verdana, Tahoma, Helvetica, Arial, sans-serif;
font-weight: bold;
}
-->
@@ -16,65 +16,64 @@
<body>
<h1>Windows Live Test</h1>
<div>
-<div id="meName" class="Name"></div>
-<div id="meImg"></div>
-<div id="signin"></div>
+ <div id="meName" class="Name"></div>
+ <div id="meImg"></div>
+ <div id="signin"></div>
</div>
<script src="//js.live.net/v5.0/wl.js" type="text/javascript" language="javascript"></script>
<script type="text/javascript" language="javascript">
- function setMe(clear) {
-
- var imgHolder = document.getElementById("meImg"),
- meNameHolder = document.getElementById("meName");
- if (clear) {
- imgHolder.innerHTML = "";
- meNameHolder.innerHTML = "";
- meImgInitialized = false;
- return;
- }
-
- if (meImgInitialized) return;
-
- var session = WL.getSession(),
- token = session != null ? session.access_token : null;
-
- if (token != null) {
- var url = "https://apis.live.net/v5.0/me/picture?access_token=" + escape(token);
- imgTagString = "<img src='" + url + "' />";
- imgHolder.innerHTML = imgTagString;
-
- WL.api({ path: "me", method: "get" }, function (response) {
- if (!response.error) {
- document.getElementById("meName").innerHTML = response.first_name + " " + response.last_name;
- }
- });
- meImgInitialized = true;
- }
-
- }
-
// Update the following values
var client_id = "%CLIENT_ID%",
scope = ["wl.signin", "wl.basic", "wl.offline_access"],
redirect_uri = "%REDIRECT_URI_PATH%/callback.aspx";
- var meImgInitialized = false;
+ function id(domId) {
+ return document.getElementById(domId);
+ }
+ function displayMe() {
+ var imgHolder = id("meImg"),
+ nameHolder = id("meName");
+
+ if (imgHolder.innerHTML != "") return;
+
+ if (WL.getSession() != null) {
+ WL.api({ path: "me/picture", method: "get" }).then(
+ function (response) {
+ if (response.location) {
+ imgHolder.innerHTML = "<img src='" + response.location + "' />";
+ }
+ }
+ );
+
+ WL.api({ path: "me", method: "get" }).then(
+ function (response) {
+ nameHolder.innerHTML = response.name;
+ }
+ );
+ }
+ }
- WL.Event.subscribe("auth.login", function () {
- setMe(false);
- });
+ function clearMe() {
+ id("meImg").innerHTML = "";
+ id("meName").innerHTML = "";
+ }
- WL.Event.subscribe("auth.logout", function () {
- setMe(true);
- });
+ WL.Event.subscribe("auth.sessionChange",
+ function (e) {
+ if (e.session) {
+ displayMe();
+ }
+ else {
+ clearMe();
+ }
+ }
+ );
WL.init({ client_id: client_id, redirect_uri: redirect_uri, response_type: "code" });
- WL.ui({ name: "signin", element: "signin", scope: scope });
-
- setMe(false);
+ WL.ui({ name: "signin", element: "signin" });
</script>
</body>
</html>
View
3 Samples/Asp.net/OAuthSample/readme.txt
@@ -62,8 +62,9 @@ f) The client code (wl.js) on the default.html page gets the access token, chang
3. Requirements
-For Asp.Net sample, you need a Windows that has IIS/Asp.Net installed.
+For Asp.Net sample, you need a Windows that has IIS/Asp.Net installed.
For Php sample, you can use Windows or Linux that has Php installed.
+Make sure your sample site is on port 80(http) or 443 (https).
=====
View
9 Samples/PHP/OauthSample/callback.php
@@ -3,6 +3,7 @@
define('ERRORCODE', 'error');
define('ERRORDESC', 'error_description');
define('ACCESSTOKEN', 'access_token');
+define('AUTHENTICATION_TOKEN', 'authentication_token');
define('CODE', 'code');
define('SCOPE', 'scope');
define('EXPIRESIN', 'expires_in');
@@ -11,10 +12,11 @@
// Update the following values
define('CLIENTID', '%CLIENT_ID%');
define('CLIENTSECRET', '%CLIENT_SECRET%');
+
// Make sure this is identical to the redirect_uri parameter passed in WL.init() call.
define('CALLBACK', '%REDIRECT_URI_PATH%/callback.php');
-define('OAUTHURL', 'https://oauth.live.com/token');
+define('OAUTHURL', 'https://login.live.com/oauth20_token.srf');
function buildQueryString($array)
{
@@ -54,7 +56,7 @@ function sendRequest(
$url,
$method = 'GET',
$data = array(),
- $headers = array('Content-type: application/x-www-form-urlencoded'))
+ $headers = array('Content-type: application/x-www-form-urlencoded;charset=UFT-8'))
{
$context = stream_context_create(array
(
@@ -78,7 +80,7 @@ function requestAccessToken($content)
if ($response !== false)
{
$authToken = json_decode($response);
- if (!empty($authToken) && !empty($authToken->{ACCESSTOKEN}) )
+ if (!empty($authToken) && !empty($authToken->{ACCESSTOKEN}))
{
return $authToken;
}
@@ -183,6 +185,7 @@ function handleTokenResponse($token, $error = null)
if (!empty($token))
{
$cookieValues[ACCESSTOKEN] = $token->{ACCESSTOKEN};
+ $cookieValues[AUTHENTICATION_TOKEN] = $token->{AUTHENTICATION_TOKEN};
$cookieValues[SCOPE] = $token->{SCOPE};
$cookieValues[EXPIRESIN] = $token->{EXPIRESIN};
View
104 Samples/PHP/OauthSample/default.html
@@ -1,80 +1,82 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Windows Live Test</title>
<style>
<!--
- .Name
- {
- font-family: Segoe UI, Verdana, Tahoma, Helvetica, Arial, sans-serif;
+ .Name {
+ font-family: 'Segoe UI', Verdana, Tahoma, Helvetica, Arial, sans-serif;
font-weight: bold;
}
+
-->
- </style>
+ </style>
</head>
<body>
<h1>Windows Live Test</h1>
+
<div>
-<div id="meName" class="Name"></div>
-<div id="meImg"></div>
-<div id="signin"></div>
+ <div id="meName" class="Name"></div>
+ <div id="meImg"></div>
+ <div id="signin"></div>
</div>
-<script src="//js.live.net/v5.0/wl.js" type="text/javascript" language="javascript"></script>
-<script type="text/javascript" language="javascript">
-
- function setMe(clear) {
-
- var imgHolder = document.getElementById("meImg"),
- meNameHolder = document.getElementById("meName");
- if (clear) {
- imgHolder.innerHTML = "";
- meNameHolder.innerHTML = "";
- meImgInitialized = false;
- return;
- }
-
- if (meImgInitialized) return;
-
- var session = WL.getSession(),
- token = session != null ? session.access_token : null;
-
- if (token != null) {
- var url = "https://apis.live.net/v5.0/me/picture?access_token=" + escape(token);
- imgTagString = "<img src='" + url + "' />";
- imgHolder.innerHTML = imgTagString;
-
- WL.api({ path: "me", method: "get" }, function (response) {
- if (!response.error) {
- document.getElementById("meName").innerHTML = response.first_name + " " + response.last_name;
- }
- });
- meImgInitialized = true;
- }
-
- }
+<script src="//js.live.net/v5.0/wl.js" type="text/javascript"></script>
+<script type="text/javascript">
// Update the following values
var client_id = "%CLIENT_ID%",
scope = ["wl.signin", "wl.basic", "wl.offline_access"],
redirect_uri = "%REDIRECT_URI_PATH%/callback.php";
- var meImgInitialized = false;
+ function id(domId) {
+ return document.getElementById(domId);
+ }
+ function displayMe() {
+ var imgHolder = id("meImg"),
+ nameHolder = id("meName");
+
+ if (imgHolder.innerHTML != "") return;
+
+ if (WL.getSession() != null) {
+ WL.api({ path: "me/picture", method: "get" }).then(
+ function (response) {
+ if (response.location) {
+ imgHolder.innerHTML = "<img src='" + response.location + "' />";
+ }
+ }
+ );
+
+ WL.api({ path: "me", method: "get" }).then(
+ function (response) {
+ nameHolder.innerHTML = response.name;
+ }
+ );
+ }
+ }
- WL.Event.subscribe("auth.login", function () {
- setMe(false);
- });
+ function clearMe() {
+ id("meImg").innerHTML = "";
+ id("meName").innerHTML = "";
+ }
- WL.Event.subscribe("auth.logout", function () {
- setMe(true);
- });
+ WL.Event.subscribe("auth.sessionChange",
+ function (e) {
+ if (e.session) {
+ displayMe();
+ }
+ else {
+ clearMe();
+ }
+ }
+ );
- WL.init({ client_id: client_id, redirect_uri: redirect_uri, response_type: "code", scope: scope });
+ WL.init({ client_id: client_id, redirect_uri: redirect_uri, response_type: "code" });
- WL.ui({ name: "signin", element: "signin", scope: scope });
+ WL.ui({ name: "signin", element: "signin" });
- setMe(false);
</script>
</body>
</html>
View
1 Samples/PHP/OauthSample/readme.txt
@@ -64,6 +64,7 @@ f) The client code (wl.js) on the default.html page gets the access token, chang
For Asp.Net sample, you need a Windows that has IIS/Asp.Net installed.
For Php sample, you can use Windows or Linux that has Php installed.
+Make sure your sample site is on port 80(http) or 443 (https).
=====

0 comments on commit 57ff575

Please sign in to comment.