Index: pkg/oauth2/README.md |
diff --git a/pkg/oauth2/README.md b/pkg/oauth2/README.md |
new file mode 100644 |
index 0000000000000000000000000000000000000000..72aff2a8ed3306f01697dc5fc3fe32ed1e3dbd89 |
--- /dev/null |
+++ b/pkg/oauth2/README.md |
@@ -0,0 +1,100 @@ |
+A client library for authenticating with a remote service via OAuth2 on |
+behalf of a user, and making authorized HTTP requests with the user's OAuth2 |
+credentials. Currently this only works where `dart:io` is available. |
+ |
+OAuth2 allows a client (the program using this library) to access and |
+manipulate a resource that's owned by a resource owner (the end user) and |
+lives on a remote server. The client directs the resource owner to an |
+authorization server (usually but not always the same as the server that |
+hosts the resource), where the resource owner tells the authorization server |
+to give the client an access token. This token serves as proof that the |
+client has permission to access resources on behalf of the resource owner. |
+ |
+OAuth2 provides several different methods for the client to obtain |
+authorization. At the time of writing, this library only supports the |
+[AuthorizationCodeGrant][] method, but further methods may be added in the |
+future. The following example uses this method to authenticate, and assumes |
+that the library is being used by a server-side application. |
+ |
+[AuthorizationCodeGrant]: https://api.dartlang.org/apidocs/channels/stable/#oauth2/oauth2.AuthorizationCodeGrant |
+ |
+```dart |
+import 'dart:io' |
+import 'package:oauth2/oauth2.dart' as oauth2; |
+ |
+// These URLs are endpoints that are provided by the authorization |
+// server. They're usually included in the server's documentation of its |
+// OAuth2 API. |
+final authorizationEndpoint = |
+ Uri.parse("http://example.com/oauth2/authorization"); |
+final tokenEndpoint = |
+ Uri.parse("http://example.com/oauth2/token"); |
+ |
+// The authorization server will issue each client a separate client |
+// identifier and secret, which allows the server to tell which client |
+// is accessing it. Some servers may also have an anonymous |
+// identifier/secret pair that any client may use. |
+// |
+// Note that clients whose source code or binary executable is readily |
+// available may not be able to make sure the client secret is kept a |
+// secret. This is fine; OAuth2 servers generally won't rely on knowing |
+// with certainty that a client is who it claims to be. |
+final identifier = "my client identifier"; |
+final secret = "my client secret"; |
+ |
+// This is a URL on your application's server. The authorization server |
+// will redirect the resource owner here once they've authorized the |
+// client. The redirection will include the authorization code in the |
+// query parameters. |
+final redirectUrl = Uri.parse("http://my-site.com/oauth2-redirect"); |
+ |
+var credentialsFile = new File("~/.myapp/credentials.json"); |
+return credentialsFile.exists().then((exists) { |
+ // If the OAuth2 credentials have already been saved from a previous |
+ // run, we just want to reload them. |
+ if (exists) { |
+ return credentialsFile.readAsString().then((json) { |
+ var credentials = new oauth2.Credentials.fromJson(json); |
+ return new oauth2.Client(identifier, secret, credentials); |
+ }); |
+ } |
+ |
+ // If we don't have OAuth2 credentials yet, we need to get the |
+ // resource owner to authorize us. We're assuming here that we're a |
+ // command-line application. |
+ var grant = new oauth2.AuthorizationCodeGrant( |
+ identifier, secret, authorizationEndpoint, tokenEndpoint); |
+ |
+ // Redirect the resource owner to the authorization URL. This will be |
+ // a URL on the authorization server (authorizationEndpoint with some |
+ // additional query parameters). Once the resource owner has |
+ // authorized, they'll be redirected to `redirectUrl` with an |
+ // authorization code. |
+ // |
+ // `redirect` is an imaginary function that redirects the resource |
+ // owner's browser. |
+ return redirect(grant.getAuthorizationUrl(redirectUrl)).then((_) { |
+ // Another imaginary function that listens for a request to |
+ // `redirectUrl`. |
+ return listen(redirectUrl); |
+ }).then((request) { |
+ // Once the user is redirected to `redirectUrl`, pass the query |
+ // parameters to the AuthorizationCodeGrant. It will validate them |
+ // and extract the authorization code to create a new Client. |
+ return grant.handleAuthorizationResponse(request.uri.queryParameters); |
+ }) |
+}).then((client) { |
+ // Once you have a Client, you can use it just like any other HTTP |
+ // client. |
+ return client.read("http://example.com/protected-resources.txt") |
+ .then((result) { |
+ // Once we're done with the client, save the credentials file. This |
+ // ensures that if the credentials were automatically refreshed |
+ // while using the client, the new credentials are available for the |
+ // next run of the program. |
+ return credentialsFile.open(FileMode.WRITE).then((file) { |
+ return file.writeString(client.credentials.toJson()); |
+ }).then((file) => file.close()).then((_) => result); |
+ }); |
+}).then(print); |
+``` |