mirror of https://gitee.com/bigwinds/arangodb
Documented OAuth2 app.
This commit is contained in:
parent
c4173ae192
commit
7c17a98ade
|
@ -1,3 +1,301 @@
|
|||
!CHAPTER The OAuth2 Authentication App
|
||||
|
||||
WRITEME
|
||||
The OAuth2 authentication app provides authentication abstractions over OAuth2 providers like Facebook, GitHub and Google. If you want to support additional providers, you can easily define your own.
|
||||
|
||||
```js
|
||||
var providers = Foxx.requireApp('/_oauth2').providers;
|
||||
```
|
||||
|
||||
!SECTION Configuration
|
||||
|
||||
The app requires no configuration, but you need to update its *providers* collection with your client ID and client secret for each provider you wish to support.
|
||||
|
||||
!SUBSECTION Registering your app with GitHub
|
||||
|
||||
If you want to use the *github* provider, you need to obtain a client ID and client secret from GitHub.
|
||||
|
||||
1. Create a regular account at [GitHub](https://github.com) or use an existing account you own.
|
||||
2. Go to [Account Settings > Applications > Register new application](https://github.com/settings/applications/new).
|
||||
3. Provide an *authorization callback URL*. This must match your *redirect_uri* later.
|
||||
4. Fill in the other required details and follow the instructions provided.
|
||||
5. Open the application page, then note down the *Client ID* and *Client Secret*.
|
||||
6. Update the *github* provider by setting its *clientId* attribute to the *Client ID* and its *clientSecret* attribute to the *Client Secret*. Don't forget to save your changes.
|
||||
|
||||
!SUBSECTION Registering your app with Facebook
|
||||
|
||||
If you want to use the *facebook* provider, you need to obtain a client ID and client secret from Facebook.
|
||||
|
||||
1. Create a regular account at [Facebook](https://www.facebook.com) or use an existing account you own.
|
||||
2. Visit the [Facebook Developers](https://developers.facebook.com) page.
|
||||
3. Click on *Apps* in the menu, then select *Register as a Developer* (the only option) and follow the instructions provided. You may need to verify your account by phone.
|
||||
4. Click on *Apps* in the menu, then select *Create a New App* and follow the instructions provided.
|
||||
5. Open the app dashboard, then note down the *App ID* and *App Secret*. The secret may be hidden by default.
|
||||
6. Click on *Settings*, then *Advanced* and enter one or more *Valid OAuth redirect URIs*. At least one of them must match your *redirect_uri* later. Don't forget to save your changes.
|
||||
7. Update the *facebook* provider by setting its *clientId* attribute to the *App ID* and its *clientSecret* attribute to the *App Secret*. Don't forget to save your changes.
|
||||
|
||||
!SUBSECTION Registering your app with Google
|
||||
|
||||
If you want to use the *google* provider, you need to obtain a client ID and client secret from Google.
|
||||
|
||||
1. Create a regular account at [Google](https://www.google.com) or use an existing account you own.
|
||||
2. Visit the [Google Developers Console](https://console.developers.google.com).
|
||||
3. Click on *Create Project*, then follow the instructions provided.
|
||||
4. When your project is ready, open the project dashboard, then click on *Enable an API*.
|
||||
5. Enable the *Google+ API* to allow your app to distinguish between different users.
|
||||
6. Open the *Credentials* page and click *Create new Client ID*, then follow the instructions provided. At least one *Authorized Redirect URI* must match your *redirect_uri* later. At least one *Authorized JavaScript Origin* must match your app's fully-qualified domain.
|
||||
7. When the Client ID is ready, note down the *Client ID* and *Client secret*.
|
||||
8. Update the *google* provider by settiing its *clientId* attribute to the *Client ID* and its *clientSecret* attribute to the *Client secret*. Don't forget to save your changes.
|
||||
|
||||
!SECTION Exceptions
|
||||
|
||||
!SUBSECTION Provider Not Found
|
||||
|
||||
Indicates a provider could not be found in the database.
|
||||
|
||||
`new providers.errors.ProviderNotFound(providerId)`
|
||||
|
||||
Thrown by the provider storage's *delete* and *get* methods if passed a provider ID that does not exist in the database.
|
||||
|
||||
@EXAMPLES
|
||||
|
||||
```js
|
||||
try {
|
||||
providers.get(invalidProviderId);
|
||||
} catch(err) {
|
||||
assertTrue(err instanceof providers.errors.ProviderNotFound);
|
||||
}
|
||||
```
|
||||
|
||||
!SECTION The provider object
|
||||
|
||||
Provider objects are instances of a Foxx model with the following attributes:
|
||||
|
||||
* *label*: a human-readable identifier for the provider (e.g. *"GitHub"*).
|
||||
* *authEndpoint*: the fully-qualified URL of the provider's [authorization endpoint](http://tools.ietf.org/html/rfc6749#section-3.1).
|
||||
* *tokenEndpoint*: the fully-qualified URL of the provider's [token endpoint](http://tools.ietf.org/html/rfc6749#section-3.2).
|
||||
* *refreshEndpoint* (optional): the fully-qualified URL of the provider's [refresh token](http://tools.ietf.org/html/rfc6749#section-6) endpoint.
|
||||
* *activeUserEndpoint* (optional): the fully-qualified URL of the provider's endpoint for fetching details about the current user.
|
||||
* *usernameTemplate* (optional): An underscore.js template for extracting the user's permanent identifier from the user's details. Default: *"<%= id %>"*.
|
||||
* *clientId*: the client ID of the app registered with the provider.
|
||||
* *clientSecret*: the client secret of the app registered with the provider.
|
||||
|
||||
!SECTION List available OAuth2 providers
|
||||
|
||||
Returns a list of OAuth2 providers that can be presented to the front-end.
|
||||
|
||||
`providers.list()`
|
||||
|
||||
Each item in the list is an object with the following properties:
|
||||
|
||||
* *_key*: *_key* of the provider.
|
||||
* *label*: a human-readable identifier that can be presented to the user.
|
||||
* *clientId*: the client ID stored for the given provider.
|
||||
|
||||
If you wish to exclude providers you don't support in your app, you need to filter the result manually.
|
||||
|
||||
@EXAMPLES
|
||||
|
||||
```js
|
||||
var supportedProviders = providers.list().filter(function(obj) {
|
||||
return Boolean(obj.clientId);
|
||||
});
|
||||
```
|
||||
|
||||
!SECTION Define a new OAuth2 provider
|
||||
|
||||
Creates a new OAuth2 provider with the given data.
|
||||
|
||||
`providers.create(data)`
|
||||
|
||||
Saves and returns a new instance of the provider model with its attributes set to the properties of the given object.
|
||||
|
||||
*Parameter*
|
||||
|
||||
* *data*: an arbitrary object, see above.
|
||||
|
||||
@EXAMPLES
|
||||
|
||||
```js
|
||||
var provider = providers.create({
|
||||
_key: 'myoauth2',
|
||||
label: 'My OAuth2 Provider',
|
||||
authEndpoint: 'https://example.com/oauth2/authorize',
|
||||
tokenEndpoint: 'https://example.com/oauth2/access_token',
|
||||
refreshEndpoint: 'https://example.com/oauth2/access_token',
|
||||
activeUserEndpoint: 'https://example.com/api/v2/users/me',
|
||||
usernameTemplate: '<%= user_id %>',
|
||||
clientId: '1234567890',
|
||||
clientSecret: 'kEyBoArDcAt'
|
||||
});
|
||||
```
|
||||
|
||||
!SECTION Fetch an existing OAuth2 provider
|
||||
|
||||
Fetches an existing OAuth2 provider from the database.
|
||||
|
||||
`providers.get(providerId)`
|
||||
|
||||
Throws a *ProviderNotFound* exception if the provider does not exist.
|
||||
|
||||
*Parameters*
|
||||
|
||||
* *providerId*: the provider's *_key*.
|
||||
|
||||
@EXAMPLES
|
||||
|
||||
```js
|
||||
var provider = providers.get('github');
|
||||
assertTrue(provider.get('_key'), 'github');
|
||||
```
|
||||
|
||||
!SECTION Delete a provider
|
||||
|
||||
There are two ways to delete a provider from the database:
|
||||
|
||||
* calling the provider storage's *delete* method with a provider's *_key* directly
|
||||
* telling a provider to delete itself
|
||||
|
||||
!SUBSECTION Delete a provider by its ID
|
||||
|
||||
Delete a provider with a given ID.
|
||||
|
||||
`providers.delete(providerId)`
|
||||
|
||||
Attempts to delete the provider with the given *providerId* from the database. If the provider does not exist, a *ProviderNotFound* exception will be thrown. The method always returns *null*.
|
||||
|
||||
*Parameter*
|
||||
|
||||
* *providerId*: a provider *_key*.
|
||||
|
||||
@EXAMPLES
|
||||
|
||||
```js
|
||||
providers.delete('github');
|
||||
```
|
||||
|
||||
!SUBSECTION Tell a provider to delete itself
|
||||
|
||||
Delete a provider from the database.
|
||||
|
||||
`provider.delete()`
|
||||
|
||||
Attempts to delete the provider from the database.
|
||||
|
||||
Returns *true* if the provider was deleted successfully.
|
||||
|
||||
Returns *false* if the provider already didn't exist.
|
||||
|
||||
@EXAMPLES
|
||||
|
||||
```js
|
||||
var provider = providers.get('github');
|
||||
provider.delete();
|
||||
```
|
||||
|
||||
!SECTION Save a provider
|
||||
|
||||
Save a provider to the database.
|
||||
|
||||
`provider.save()`
|
||||
|
||||
In order to commit changes made to the provider in your code, you need to call this method.
|
||||
|
||||
@EXAMPLES
|
||||
|
||||
```js
|
||||
provider.set('clientId', '1234567890');
|
||||
provider.set('clientSecret', 'kEyBoArDcAt');
|
||||
provider.save();
|
||||
```
|
||||
|
||||
|
||||
!SECTION Get the authorization URL of a provider
|
||||
|
||||
Generates the authorization URL for the authorization endpoint of the provider.
|
||||
|
||||
`provider.getAuthUrl(redirect_uri, args)`
|
||||
|
||||
Returns a fully-qualified URL for the authorization endpoint of the provider by appending the provider object's client ID and any additional arguments from *args* to the provider object's *authEndpoint*.
|
||||
|
||||
*Parameter*
|
||||
|
||||
* *redirect_uri*: the fully-qualified URL of your app's OAuth2 callback.
|
||||
* *args* (optional): an object with any of the following properties:
|
||||
* *response_type* (optional): See [RFC 6749](http://tools.ietf.org/html/rfc6749). Default: *"code"*.
|
||||
|
||||
!SECTION _getTokenRequest
|
||||
|
||||
(Internal.) Generates the token URL and request body for token endpoint of the provider.
|
||||
|
||||
`provider._getTokenRequest(code, redirect_uri, args)`
|
||||
|
||||
Returns an object with two properties:
|
||||
|
||||
* *url*: the fully-qualified URL for the token endpoint.
|
||||
* *body*: the form-encoded request body for the token endpoint created by appending the provider object's client ID, client secret and any additional arguments from *args* to the provider object's *tokenEndpoint*.
|
||||
|
||||
*Parameter*
|
||||
|
||||
* *code*: a grant code returned by the provider's authorization endpoint.
|
||||
* *redirect_uri*: the original callback URL with which the code was requested.
|
||||
* *args* (optional): an object with any of the following properties:
|
||||
* *grant_type* (optional): see [RFC 6749](http://tools.ietf.org/html/rfc6749). Default: *"authorization_code"*.
|
||||
|
||||
!SECTION Exchange a grant code for an access token
|
||||
|
||||
Exchanges a grant code for an access token.
|
||||
|
||||
`provider.exchangeGrantToken(code, redirect_uri)`
|
||||
|
||||
Performs a *POST* response to the provider object's *tokenEndpoint* and returns the parsed response body.
|
||||
|
||||
Throws an exception if the remote server responds with an empty response body.
|
||||
|
||||
*Parameter*
|
||||
|
||||
* *code*: a grant code returned by the provider's authorization endpoint.
|
||||
* *redirect_uri*: the original callback URL with which the code was requested.
|
||||
* *args* (optional): an object with any of the following properties:
|
||||
* *grant_type* (optional): see [RFC 6749](http://tools.ietf.org/html/rfc6749). Default: *"authorization_code"*.
|
||||
|
||||
!SECTION Fetch the active user
|
||||
|
||||
Fetches details of the active user.
|
||||
|
||||
`provider.fetchActiveUser(access_token)`
|
||||
|
||||
Performs a *GET* response to the provider object's *activeUserEndpoint* and returns the parsed response body.
|
||||
|
||||
Throws an exception if the remote server responds with an empty response body.
|
||||
|
||||
Also throws an exception if the provider object has no *activeUserEndpoint*.
|
||||
|
||||
*Parameter*
|
||||
|
||||
* *access_token*: an OAuth2 access token as returned by *exchangeGrantToken*.
|
||||
|
||||
@EXAMPLES
|
||||
|
||||
```js
|
||||
var authData = provider.exchangeGrantToken(code, redirect_uri);
|
||||
var userData = provider.fetchActiveUser(authData.access_token);
|
||||
```
|
||||
|
||||
!SECTION Get a user's identifier
|
||||
|
||||
Fetches the user's identifier from a user object returned by the provider.
|
||||
|
||||
`provider.getUsername(userData)`
|
||||
|
||||
Applies the provider's *usernameTemplate* to the given user object.
|
||||
|
||||
*Parameter*
|
||||
|
||||
* *userData*: the object returned by *getActiveUser*.
|
||||
|
||||
@EXAMPLES
|
||||
|
||||
```js
|
||||
var userData = provider.fetchActiveUser(access_token);
|
||||
var username = provider.getUsername(userData);
|
||||
```
|
||||
|
|
Loading…
Reference in New Issue