mirror of
https://github.com/zoriya/octokit.net.git
synced 2025-12-06 07:16:09 +00:00
101 lines
4.2 KiB
Markdown
101 lines
4.2 KiB
Markdown
## OAuth Flow
|
|
|
|
If you have a service which needs to interact with the GitHub API on behalf of a user, you should use the OAuth flow. [Phil Haack](https://haacked.com) has written a great [blog post](http://haacked.com/archive/2014/04/24/octokit-oauth/) on using Octokit in ASP.NET, and even has a [demo project](https://github.com/Haacked/octokit-oauth-demo) you can try out, so this will just go over the specific APIs in more detail.
|
|
|
|
### Setup
|
|
|
|
First, you need to register your application on GitHub (or GitHub Enterprise). While logged in, go to your account settings and click the Applications tab. Then click "Register new application".
|
|
|
|
Or just navigate to [https://github.com/settings/applications/new](https://github.com/settings/applications/new) if you're lazy.
|
|
|
|
Fill in some details about your application:
|
|
|
|

|
|
|
|
Then click "Register application", and you'll get your client id and client secret.
|
|
|
|

|
|
|
|
### Starting the OAuth Flow
|
|
|
|
We'll use these in a few places, so define these as private fields:
|
|
|
|
```csharp
|
|
var clientId = "some-id-here";
|
|
var clientSecret = "some-id-here";
|
|
var client = new GitHubClient(new ProductHeaderValue("my-cool-app"));
|
|
```
|
|
|
|
To start the authentication flow, you need to craft a URL indicating your application needs to authenticate on behalf of the current user.
|
|
|
|
```csharp
|
|
// NOTE: this is not required, but highly recommended!
|
|
// ask the ASP.NET Membership provider to generate a random value
|
|
// and store it in the current user's session
|
|
string csrf = Membership.GeneratePassword(24, 1);
|
|
Session["CSRF:State"] = csrf;
|
|
|
|
var request = new OauthLoginRequest(clientId)
|
|
{
|
|
Scopes = {"user", "notifications"},
|
|
State = csrf
|
|
};
|
|
|
|
// NOTE: user must be navigated to this URL
|
|
var oauthLoginUrl = client.Oauth.GetGitHubLoginUrl(request);
|
|
```
|
|
|
|
Scopes are keys which specify the permissions the application needs. If you don't specify a `Scopes` value, your application will only have read access to the user's public data (repository, user info, etc). There's lots of different scopes available for different interactions with user data, so have a look at the [documentation](https://developer.github.com/v3/oauth/#scopes) for more information.
|
|
|
|
### Generating the token
|
|
|
|
Once the user has been navigated to the URL above and clicked "Authorize Application", you will receive a callback at the default Callback URL for your application. If you require a more flexible URL, you can override this by specifying a different URL when creating the request.
|
|
|
|
```csharp
|
|
var request = new OauthLoginRequest(clientId)
|
|
{
|
|
// other parameters
|
|
RedirectUri = new Url("https://mycoolsite.com/some/uri")
|
|
};
|
|
```
|
|
|
|
The callback will have two parameters, the code generated by the GitHub API and some additional state - this is specifically to prevent CSRF (Cross-Site Request Forgery) attacks and is highly recommended.
|
|
|
|
With this code you can then request an access token by providing your client secret. This doesn't require any user interaction, so it can be done in the background.
|
|
|
|
```csharp
|
|
public async Task<ActionResult> Authorize(string code, string state)
|
|
{
|
|
if (String.IsNullOrEmpty(code))
|
|
return RedirectToAction("Index");
|
|
|
|
var expectedState = Session["CSRF:State"] as string;
|
|
if (state != expectedState) throw new InvalidOperationException("SECURITY FAIL!");
|
|
Session["CSRF:State"] = null;
|
|
|
|
var request = new OauthTokenRequest(clientId, clientSecret, code);
|
|
var token = await client.Oauth.CreateAccessToken(request);
|
|
Session["OAuthToken"] = token.AccessToken;
|
|
|
|
return RedirectToAction("Index");
|
|
}
|
|
```
|
|
|
|
And now you have an access token, you can set up your credentials to use this token:
|
|
|
|
```csharp
|
|
// repositories which include public and private repositories.
|
|
public async Task<ActionResult> Index()
|
|
{
|
|
var accessToken = Session["OAuthToken"] as string;
|
|
if (accessToken != null)
|
|
{
|
|
client.Credentials = new Credentials(accessToken);
|
|
|
|
var repositories = await client.Repository.GetAllForCurrent();
|
|
}
|
|
|
|
/* TODO: all the rest of the webapp */
|
|
}
|
|
```
|