Setting up an authentication page
In the Skybrud.Social.Facebook package, the FacebookClient class is primarily responsible for the raw communication with the Facebook Graph API. It does however also contain relevant logic for handling authentication with the Graph API - eg. so you can set up your own authentication.
An authentication will allow your users to login with their Facebook API, which in return will give you a user access token that you can use to access the Graph API on their behalf.
The examples below will show you how to set up an authentication - using a ASP.NET MVC view specifically. To get started, you need to initialize an instance of the FacebookClient class with some information about your Facebook app.
FacebookOAuthClient client = new FacebookOAuthClient {
ClientId = "Insert your app/client ID here",
ClientSecret = "Insert your app/client secret",
RedirectUri = "http://social.abjerner/facebook/oauth/"
};
Generating the authorization URL
Authentication starts by redirecting the user to a page at Facebook.com where the user will grant (or refuse) that your app can gain access to make API calls on their behalf. In OAuth terminology, the URL of this page is called the authorization URL. The client instance from the example above can help you generate this URL:
string authorizationUrl = client.GetAuthorizationUrl(state);
For this method, you must specify a state parameter, which is a random generated value that you will later need to approve the user once he/she is redirected back to your site. You can store the state in a session or similar. It is part of the OAuth 2.0 security to validate the user once Facebook redirects the user back to your authentication page.
When a user grants your app access to their Facebook account, you don't just have access to everything on their account. Like most OAuth-based API, Facebook uses scopes to determine what your app will have access to. A single scope can be described as permission to some kind of resource or property - eg. the email
scope will let your app read the corresponding email
property of the authenticated user.
By not passing any additional parameters to the GetAuthorizationUrl
method, as shown in the example above, your app will not be granted any permissions, other than getting very basic information about the authenticated user - eg. their name.
If you need any additional scopes or permissions, you can request them during the authentication process:
string authorizationUrl = client.GetAuthorizationUrl(state, FacebookScopes.Email + FacebookScopes.PublishActions);
By specifying a second parameter - in this case with the added value of FacebookScopes.Email
and FacebookScopes.PublishActions
- you request the user to grant your app access to the email
and publish_actions
scopes. The user will be informed about this once redirected to the authorization page at Facebook.com.
It is however worth mentioning, that if a user has already granted your app access to the specified scopes, they will simply be redirected back to your authentication page.
Getting the authorization code
Once the user confirms (or denies) your app and the requested scopes/permissions, the user is redirected back to your page. If confirmed, a code
parameter will be included in the query string. This parameter is an authorization code that you will need to obtain the actual access token of the user.
Obtaining an access token
The access token can be obtained using the GetAccessTokenFromAuthCode
method, where the response body will expose the access token.
For the example below, the parameter for the method is the authorization code received when the user has successfully logged in through the Facebook authorization dialog, and been redirected back to your site. At this point, the code
parameter in the query string will contain the authorization code.
The code for exchanging the authorization code for the access token will look like:
FacebookTokenResponse response = client.GetAccessTokenFromAuthCode(code);
string accessToken = response.Body.AccessToken;
A user access token obtained this way will expire after 60 days, in which case the user will have to authenticate again to keep their access to the API.
Initializing an instance of FacebookService
Once you have obtained an access token, you can initialize a new instance of the FacebookService class as shown in the example below:
FacebookService service = FacebookService.CreateFromAccessToken("Insert your access token here");
The FacebookService class serves as your starting point to making calls to the Facebook Graph API.
Complete example
In the example below, I've tried to demonstrate how an authentication page can be implemented (involving the steps explained above).
Notice that the example generates a state
value that is saved to the user's session. When redirecting the user to Facebook's authorization page, we supply the state, and once the user confirms (or cancels) the authorization, the same state is specified in the URL the user is redirected back to (at your site). We can then check whether the state is saved in the user session to make sure it's still the same user making the request.
@using Skybrud.Social.Facebook
@using Skybrud.Social.Facebook.OAuth
@using Skybrud.Social.Facebook.Responses.Authentication
@using Skybrud.Social.Facebook.Scopes
@{
FacebookOAuthClient client = new FacebookOAuthClient {
ClientId = "Insert your app/client ID here",
ClientSecret = "Insert your app/client secret",
RedirectUri = "http://social.abjerner/facebook/oauth/"
};
if (Request.QueryString["do"] == "login") {
string state = Guid.NewGuid().ToString();
string stateKey = "FacebookOAuthState_" + state;
Session[stateKey] = Request.RawUrl;
string authorizationUrl = client.GetAuthorizationUrl(state, FacebookScopes.Email + FacebookScopes.PublishActions);
Response.Redirect(authorizationUrl);
} else if (Request.QueryString["code"] != null) {
string state = Request.QueryString["state"];
string code = Request.QueryString["code"];
string stateKey = "FacebookOAuthState_" + state;
if (Session[stateKey] == null) {
<p>Has your session expired?</p>
<p>
<a class="btn btn-default" href="@Url.Action("OAuth")?do=login">Re-try login</a>
</p>
return;
}
FacebookTokenResponse response = client.GetAccessTokenFromAuthCode(code);
FacebookService service = FacebookService.CreateFromAccessToken(response.Body.AccessToken);
<div>Access Token:</div>
<pre>@response.Body.AccessToken</pre>
<div>Expires in:</div>
<pre>@response.Body.ExpiresIn</pre>
<div>Token type:</div>
<pre>@response.Body.TokenType</pre>
return;
}
<p>
<a class="btn btn-default" href="@Url.Action("OAuth")?do=login">Login with Facebook</a>
</p>
}