-
-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into support-http
- Loading branch information
Showing
97 changed files
with
6,189 additions
and
757 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,3 +3,4 @@ coverage | |
.github | ||
examples | ||
node_modules | ||
docs |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
## Getting started with Bearer Token authentication | ||
|
||
Bearer Token authentication is one of the most popular forms of authentication and is widely used because of its percieved security. This guide will walk through how to implement bearer token authentication in Glee. | ||
|
||
A sample `asyncapi.yaml` for a server with security requirements and user password security scheme is shown below: | ||
|
||
```yaml | ||
##server asyncAPI schema | ||
asyncapi: 2.6.0 | ||
info: | ||
title: AsyncAPI IMDB server | ||
version: 1.0.0 | ||
description: This app is a dummy server that would stream the trending/upcoming anime. | ||
servers: | ||
trendingAnimeServer: | ||
url: 'http://localhost:8081' | ||
protocol: http | ||
security: | ||
- token: [] | ||
|
||
... | ||
|
||
components: | ||
securitySchemes: | ||
token: | ||
type: http | ||
scheme: bearer | ||
bearerFormat: JWT | ||
|
||
``` | ||
|
||
A sample `asyncapi.yaml` for a client that implements some of the requirements of the server above: | ||
|
||
```yaml | ||
##client asyncAPI schema | ||
servers: | ||
trendingAnime: | ||
url: http://localhost:8081 | ||
protocol: http | ||
security: | ||
- token: [] | ||
testwebhook: | ||
url: ws://localhost:9000 | ||
protocol: ws | ||
x-remoteServers: | ||
- trendingAnime | ||
|
||
... | ||
|
||
components: | ||
securitySchemes: | ||
token: | ||
type: http | ||
scheme: bearer | ||
bearerFormat: JWT | ||
|
||
``` | ||
|
||
**The Client asyncapi.yaml file does't need to implement all the security requirements in the server, it only needs to implement the ones that it uses.** | ||
|
||
### Client Side | ||
|
||
Following the client `asyncapi.yaml` file above, create a file named `trendingAnime.ts` in the `auth` directory, since that is the server that has the security Property. | ||
|
||
```bash | ||
touch auth/trendingAnime.ts | ||
``` | ||
|
||
When using the `token` security scheme, it is important that you pass the parameters as follows: | ||
|
||
```js | ||
export async clientAuth({ parsedAsyncAPI, serverName }) { | ||
return { | ||
token: process.env.TOKEN | ||
} | ||
} | ||
``` | ||
|
||
`token` should be the name of the security requirement as specified in your `asyncapi.yaml` file, and it's value should be a string. | ||
|
||
### Server side | ||
|
||
From the server `asyncapi.yaml` file above, create a file named `trendingAnimeServer.ts` in the `auth` directory, since that is the server that has the security Property. | ||
|
||
```bash | ||
touch auth/trendingAnimeServer.ts | ||
``` | ||
|
||
On the server side, you can retrieve the values as follows | ||
|
||
```js | ||
|
||
export async serverAuth({ authProps, done }) { | ||
authProps.getToken() | ||
|
||
done(true) | ||
} | ||
|
||
``` | ||
|
||
`getToken()` return a string which contains the token that was sent from the client. | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
## Getting started with httpAPIKey authentication | ||
|
||
This guide will walk through how to implement authentication using the `httpAPiKey` security scheme in Glee. | ||
|
||
A sample `asyncapi.yaml` for a server with security requirements and user `HttpApiKey` security scheme is shown below: | ||
|
||
```yaml | ||
##server asyncAPI schema | ||
asyncapi: 2.6.0 | ||
info: | ||
title: AsyncAPI IMDB server | ||
version: 1.0.0 | ||
description: This app is a dummy server that would stream the trending/upcoming anime. | ||
servers: | ||
trendingAnimeServer: | ||
url: 'http://localhost:8081' | ||
protocol: http | ||
security: | ||
- apiKey: [] | ||
|
||
... | ||
|
||
components: | ||
securitySchemes: | ||
apiKey: | ||
type: httpApiKey | ||
name: api_key | ||
in: query | ||
|
||
``` | ||
|
||
A sample `asyncapi.yaml` for a client that implements some of the requirements of the server above: | ||
|
||
```yaml | ||
##client asyncAPI schema | ||
servers: | ||
trendingAnime: | ||
url: http://localhost:8081 | ||
protocol: http | ||
security: | ||
- apiKey: [] | ||
testwebhook: | ||
url: ws://localhost:9000 | ||
protocol: ws | ||
x-remoteServers: | ||
- trendingAnime | ||
|
||
... | ||
|
||
components: | ||
securitySchemes: | ||
apiKey: | ||
type: httpApiKey | ||
name: api_key | ||
in: query | ||
|
||
|
||
``` | ||
|
||
The `httpApiKey` could be in either the header or query parameter. | ||
|
||
**The Client asyncapi.yaml file does not need to implement all the security requirements in the server, it only needs to implement the ones that it uses.** | ||
|
||
### Client Side | ||
|
||
Following the client `asyncapi.yaml` file above, create a file named `trendingAnime.ts` in the `auth` directory, since that is the server that has the security Property. | ||
|
||
```bash | ||
touch auth/trendingAnime.ts | ||
``` | ||
|
||
When using the `HttpApiKey` security scheme, it is important that you pass the parameters as follows: | ||
|
||
```js | ||
export async clientAuth({ parsedAsyncAPI, serverName }) { | ||
return { | ||
apiKey: process.env.APIKEY | ||
} | ||
} | ||
``` | ||
|
||
`apiKey` should be the name of the security requirement as specified in your `asyncapi.yaml` file, and it's value should be a string. | ||
|
||
|
||
### Server side | ||
|
||
From the server `asyncapi.yaml` file above, create a file named `trendingAnimeServer.ts` in the `auth` directory, since that is the server that has the security Property. | ||
|
||
```bash | ||
touch auth/trendingAnimeServer.ts | ||
``` | ||
|
||
On the server side, you can retrieve the values as follows | ||
|
||
```js | ||
|
||
export async serverAuth({ authProps, done }) { | ||
authProps.getHttpAPIKeys('api_key')() | ||
|
||
done(true) | ||
} | ||
|
||
``` | ||
|
||
`getHttpAPIKeys(name)` takes a name parameter to specify the name of the httpApiKey that is desired. Then it returns an object containing the httpApiKey value that was sent from the client. | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
# Authentication | ||
|
||
Authentication in Glee can be done using authentication functions. Authentication functions are files that export either one or both of the `clientAuth` and `serverAuth` Node.js functions: | ||
|
||
```js | ||
/* websocket.js */ | ||
|
||
export async function serverAuth({ authProps, done }) { | ||
//server auth logic | ||
} | ||
|
||
export async function clientAuth({ parsedAsyncAPI, serverName }) { | ||
//client auth logic | ||
} | ||
``` | ||
|
||
Glee looks for authentication files in the `auth` directory by default but it can be configured using [glee config file](../config-file.md). | ||
The name of the authentication file should be the name of the targeted server that the authentication logic should work for. | ||
|
||
## Supported Authentication Values in asyncapi.yaml file | ||
|
||
AsyncAPI currently supports a variety of authentication formats as specified in the [documentation](https://www.asyncapi.com/docs/reference/specification/v2.6.0#securitySchemeObject), however Glee supports the following authentication schemas. | ||
|
||
- userPassword | ||
- Bearer token | ||
- HttpPApiKey | ||
- ApiKey | ||
|
||
A sample `asyncapi.yaml` for a server with security requirements and a `userPassword` security schemes is shown below: | ||
|
||
```yaml | ||
##server asyncAPI schema | ||
asyncapi: 2.6.0 | ||
info: | ||
title: AsyncAPI IMDB server | ||
version: 1.0.0 | ||
description: This app is a dummy server that would stream the trending/upcoming anime. | ||
servers: | ||
trendingAnimeServer: | ||
url: 'http://localhost:8081' | ||
protocol: http | ||
security: | ||
- userPass: [] | ||
|
||
... | ||
|
||
components: | ||
securitySchemes: | ||
userPass: | ||
type: userPassword | ||
|
||
``` | ||
|
||
A sample `asyncapi.yaml` for a client that implements some of the requirements of the server above: | ||
|
||
```yaml | ||
##client asyncAPI schema | ||
servers: | ||
trendingAnime: | ||
url: http://localhost:8081 | ||
protocol: http | ||
security: | ||
- userPass: [] | ||
testwebhook: | ||
url: ws://localhost:9000 | ||
protocol: ws | ||
x-remoteServers: | ||
- trendingAnime | ||
|
||
... | ||
|
||
components: | ||
securitySchemes: | ||
userPass: | ||
type: userPassword | ||
|
||
``` | ||
|
||
**The Client asyncapi.yaml file does not need to implement all the security requirements in the server, it only needs to implement the ones that it uses.** | ||
|
||
|
||
Glee can act as both a server and a client at the same time. Hence the need for `serverAuth` and `clientAuth`. Glee acts as a client when the `x-remoteServers` property is present in the `asyncapi.yaml` file. | ||
|
||
When Glee acts as a client, it can connect to a Glee server, and when Glee acts as a server it accepts connection from other Glee clients. Hence a Glee application can both accept connections from clients while also sending requests to other Glee applications (servers) ath the same time. | ||
|
||
When a security requirement is specified in the `asyncapi.yaml` file and Glee acts as a server, the `serverAuth` function should be implemented, if Glee acts as a client then the `clientAuth` function should be implemented. If Glee is being used as both client and server, then it should have both the `clientAuth` and `serverAuth` functions. | ||
|
||
## Server Authentication in Glee | ||
|
||
The `serverAuth` function takes an argument that can be destructured as follows | ||
|
||
| Attribute | Description | | ||
| ---------- | --------------------------------------------------------------- | | ||
| done | The done function that tells the server to proceed. | | ||
| authProps | The authentication parameters recieved from the client. | | ||
| serverName | The name of the server/broker from which the event was emitted. | | ||
| doc | The parsedAsyncAPI schema | | ||
|
||
### done() | ||
|
||
The `done` parameter in the `serverAuth` function allows the broker/server to know what to do next depending on the boolean value you pass to it. | ||
|
||
```js | ||
/* websocket.js */ | ||
|
||
export async function serverAuth({ authProps, done }) { | ||
// done(true) | ||
//done(false, 401, "Unauthorized") | ||
// done(false) | ||
} | ||
``` | ||
|
||
When `true` is passed to the done parameter, the server/broker knows to go ahead and allow the client to connect, which means authentication has succeeded. However if the `done` parameter is called with `false` then the server knows to throw an error message and reject the client, which means authenticatio has failed. | ||
|
||
`done()` should always be the last thing called in a `serverAuth` function, Glee won't execute any logic beyond the `done()` call. | ||
|
||
### authProps | ||
|
||
`authProps` implements a couple of methods that allows the server to retrieve the authentication parameters from the client, below are the current available methods; | ||
|
||
```js | ||
export async function serverAuth({ authProps, done }) { | ||
//some network request | ||
|
||
authProps.getOauthToken() | ||
authProps.getHttpAPIKeys('api_key') | ||
authProps.getToken() | ||
authProps.getUserPass() | ||
|
||
// done(false, 401, "Unauthorized"); | ||
done(false) | ||
} | ||
``` | ||
|
||
| Method | Description | | ||
| ---------------------- | ------------------------------------------------------------------------------------------------ | | ||
| `getOauthToken()` | returns the oauth authentication parameter | | ||
| `getHttpAPIKeys(name)` | returns the HttpAPIKeys parameter with the specified name from either headers or query parameter | | ||
| `getToken()` | returns the http bearer token parameter | | ||
| `getUserPass()` | returns username and password parameters | | ||
|
||
## Client Authentication in Glee | ||
|
||
The `clientAuth` function also takes an argument, and it's argument can be destructured as follows | ||
|
||
| Attribute | Description | | ||
| -------------- | ------------------------------------------------------------------------------------- | | ||
| parsedAsyncAPI | The parsedAsyncAPI schema. | | ||
| serverName | The name of the server/broker from with the authentication parameters are being sent. | | ||
|
||
### possible authentication parameters | ||
|
||
The possible authentication parameters are shown in the code snippet below: | ||
|
||
```js | ||
export async function clientAuth({ serverName }) { | ||
return { | ||
token: process.env.TOKEN, | ||
oauth: process.env.OAUTH2, | ||
apiKey: process.env.APIKEY, | ||
userPass: { | ||
user: process.env.user, | ||
password: process.env.password, | ||
}, | ||
} | ||
} | ||
``` | ||
|
||
**The name of the authentication parameters should be the same as the names specified in the asyncAPI.yaml file.** | ||
|
||
| auth type | values | | ||
| ------------------------------------- | ---------------------------------------------------------------------- | | ||
| http bearer (JWT) | Value should be a JWT string | | ||
| Oauth2 | The value should should be a string | | ||
| httpApiKey in headers or query params | The value should be a string | | ||
| userPass | The value should be an object with the user and password as properties | |
Oops, something went wrong.