wip(backend): concluded apikeys routes and docs
This commit is contained in:
parent
d563bb2d17
commit
bd7c3e8b6e
9 changed files with 415 additions and 45 deletions
|
@ -12,38 +12,39 @@ refer to [the section on authenticating to the
|
|||
API](/reference/backend/api#authentication).
|
||||
</Tip>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Create a new API key
|
||||
|
||||
Create a new API key. The API key will belong to the user who is authenticated
|
||||
when making the call. Supported for both JWT and KEY authentication.
|
||||
|
||||
<Note compact>
|
||||
The response to this API call is the only time the secret will be
|
||||
revealed.
|
||||
</Note>
|
||||
|
||||
### Endpoints
|
||||
|
||||
| Method | Path | Description |
|
||||
| ------ | ---- | ----------- |
|
||||
| `POST` | `/apikey/jwt` | Create a new API key. Endpoint for JWT authentication |
|
||||
| `POST` | `/apikey/key` | Create a new API key. Endpoint for API key authentication |
|
||||
| Method | Path | Description | Auth |
|
||||
| ------ | ---- | ----------- | ---- |
|
||||
| <Method post /> | `/apikey/jwt` | Create a new API key | _jwt_ |
|
||||
| <Method post /> | `/apikey/key` | Create a new API key | _key_ |
|
||||
|
||||
### Parameters
|
||||
<Tabs tabs="Request, Response">
|
||||
<Tab>
|
||||
| Variable | Type | Description |
|
||||
| -------- | -------- | ----------- |
|
||||
| `name` | `string` | Create a new API key. Endpoint for JWT authentication |
|
||||
| `level` | `number` | A privilege level from 0 to 8. |
|
||||
| `expiresIn` | `number` | The number of seconds until this key expires. |
|
||||
| Where | Variable | Type | Description |
|
||||
| ----- | ------------- | -------- | ----------- |
|
||||
| _body_ | `name` | `string` | Create a new API key. Endpoint for JWT authentication |
|
||||
| _body_ | `level` | `number` | A privilege level from 0 to 8. |
|
||||
| _body_ | `expiresIn` | `number` | body | The number of seconds until this key expires. |
|
||||
</Tab>
|
||||
<Tab>
|
||||
Returns status code `200` on success, `400` on if the request is malformed, and
|
||||
`500` on server error.
|
||||
Returns HTTP status code <StatusCode status="201"/> on success, <StatusCode status="400"/> if
|
||||
the request is malformed, and <StatusCode status="500"/> on server error.
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | `string` | `success` on success, and `error` on error |
|
||||
| `result` | `string` | `created` on success, and `error` on error |
|
||||
| `apikey.key` | `string` | The API key |
|
||||
| `apikey.secret` | `string` | The API secret |
|
||||
| `apikey.level` | `number` | The privilege level of the API key |
|
||||
|
@ -57,7 +58,7 @@ Returns status code `200` on success, `400` on if the request is malformed, and
|
|||
<Tabs tabs="Request, Response">
|
||||
<Tab>
|
||||
```js
|
||||
const token = axios.post(
|
||||
const apiKey = axios.post(
|
||||
'https://backend.freesewing.org/apikey/jwt',
|
||||
{
|
||||
name: 'My first API key',
|
||||
|
@ -90,6 +91,185 @@ const token = axios.post(
|
|||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## Read an API key
|
||||
|
||||
Reads an existing API key. Note that the API secret can only be retrieved at
|
||||
the moment the API key is created.
|
||||
|
||||
<Note compact>
|
||||
You need the `admin` role to read API keys of other users
|
||||
</Note>
|
||||
### Endpoints
|
||||
|
||||
| Method | Path | Description | Auth |
|
||||
| ------ | ---- | ----------- | ---- |
|
||||
| <Method get /> | `/apikey/:id/jwt` | Reads an API key | _jwt_ |
|
||||
| <Method get /> | `/apikey/:id/key` | Reads an API key | _key_ |
|
||||
|
||||
### Parameters
|
||||
<Tabs tabs="Request, Response">
|
||||
<Tab>
|
||||
| Where | Variable | Type | Description |
|
||||
| ----- | ----------- | -------- | ----------- |
|
||||
| _url_ | `:id` | `string` | The `key` field of the API key |
|
||||
</Tab>
|
||||
<Tab>
|
||||
Returns HTTP status code <StatusCode status="200"/> on success, <StatusCode status="400"/> if
|
||||
the request is malformed, <StatusCode status="404"/> if the key is not found,
|
||||
and <StatusCode status="500"/> on server error.
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | `string` | `success` on success, and `error` on error |
|
||||
| `apikey.key` | `string` | The API key |
|
||||
| `apikey.level` | `number` | The privilege level of the API key |
|
||||
| `apikey.expiresAt` | `string` | A string representation of the moment the API key expires |
|
||||
| `apikey.name` | `string` | The name of the API key |
|
||||
| `apikey.userId` | `number` | The ID of the user who created the API key |
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
### Example
|
||||
<Tabs tabs="Request, Response">
|
||||
<Tab>
|
||||
```js
|
||||
const keyInfo = axios.get(
|
||||
'https://backend.freesewing.org/apikey/7ea12968-7758-40b6-8c73-75cc99be762b/jwt',
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
</Tab>
|
||||
<Tab>
|
||||
|
||||
```json
|
||||
{
|
||||
result: 'success',
|
||||
apikey: {
|
||||
key: '7ea12968-7758-40b6-8c73-75cc99be762b',
|
||||
level: 3,
|
||||
expiresAt: '2022-11-06T15:57:30.190Z',
|
||||
name: 'My first API key',
|
||||
userId: 61
|
||||
}
|
||||
}
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## Read the current API key
|
||||
|
||||
Reads the API key with which the current request was authenticated.
|
||||
|
||||
### Endpoints
|
||||
|
||||
| Method | Path | Description | Auth |
|
||||
| ------ | ---- | ----------- | ---- |
|
||||
| <Method get /> | `/whoami/key` | Reads the current API key | _key_ |
|
||||
|
||||
### Parameters
|
||||
<Tabs tabs="Request, Response">
|
||||
<Tab>
|
||||
<Note compact>This endpoint takes no parameters</Note>
|
||||
</Tab>
|
||||
<Tab>
|
||||
Returns status code `200` on success, `400` on if the request is malformed,
|
||||
`404` if the key is not found, and `500` on server error.
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | `string` | `success` on success, and `error` on error |
|
||||
| `apikey.key` | `string` | The API key |
|
||||
| `apikey.level` | `number` | The privilege level of the API key |
|
||||
| `apikey.expiresAt` | `string` | A string representation of the moment the API key expires |
|
||||
| `apikey.name` | `string` | The name of the API key |
|
||||
| `apikey.userId` | `number` | The ID of the user who created the API key |
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
### Example
|
||||
<Tabs tabs="Request, Response">
|
||||
<Tab>
|
||||
```js
|
||||
const keyInfo = axios.get(
|
||||
'https://backend.freesewing.org/whoami/key',
|
||||
{
|
||||
auth: {
|
||||
username: apikey.key,
|
||||
password: apikey.secret,
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
</Tab>
|
||||
<Tab>
|
||||
|
||||
```json
|
||||
{
|
||||
result: 'success',
|
||||
apikey: {
|
||||
key: '7ea12968-7758-40b6-8c73-75cc99be762b',
|
||||
level: 3,
|
||||
expiresAt: '2022-11-06T15:57:30.190Z',
|
||||
name: 'My first API key',
|
||||
userId: 61
|
||||
}
|
||||
}
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
|
||||
## Remove an API key
|
||||
|
||||
Removes an existing API key.
|
||||
|
||||
<Note compact>
|
||||
You need the `admin` role to remove API keys of other users
|
||||
</Note>
|
||||
|
||||
### Endpoints
|
||||
|
||||
| Method | Path | Description | Auth |
|
||||
| ------ | ---- | ----------- | ---- |
|
||||
| <Method delete /> | `/apikey/:id/jwt` | Removes an API key | _jwt_ |
|
||||
| <Method delete /> | `/apikey/:id/key` | Removes an API key | _key_ |
|
||||
|
||||
### Parameters
|
||||
<Tabs tabs="Request, Response">
|
||||
<Tab>
|
||||
| Where | Variable | Type | Description |
|
||||
| ----- | ----------- | -------- | ----------- |
|
||||
| _url_ | `:id` | `string` | The `key` field of the API key |
|
||||
</Tab>
|
||||
<Tab>
|
||||
Returns HTTP status code <StatusCode status="204"/> on success, <StatusCode status="400"/> if
|
||||
the request is malformed, <StatusCode status="404"/> if the key is not found,
|
||||
and <StatusCode status="500"/> on server error.
|
||||
</Tab>
|
||||
</Tabs>
|
||||
### Example
|
||||
<Tabs tabs="Request, Response">
|
||||
<Tab>
|
||||
```js
|
||||
const keyInfo = axios.get(
|
||||
'https://backend.freesewing.org/apikey/7ea12968-7758-40b6-8c73-75cc99be762b/jwt',
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
</Tab>
|
||||
<Tab>
|
||||
<Note compact>Status code <StatusCode status="204"/> (no content) does not come with a body</Note>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## Notes
|
||||
|
||||
The following is good to keep in mind when working with API keys:
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
title: REST API
|
||||
title: Backend REST API
|
||||
linktitle: REST API
|
||||
---
|
||||
|
||||
This is the reference documentation for the FreeSewing backend REST API.
|
||||
|
@ -19,30 +20,35 @@ automation tasks such as creating issues on Github.
|
|||
|
||||
## Authentication
|
||||
|
||||
This API is not accessible without authentication.
|
||||
Apart from a handlful of API endpoints that are accessible without
|
||||
authentication (typically the ones dealing with the signup flow or password
|
||||
recovery), this API requires authentication.
|
||||
|
||||
The FreeSewing backend API allows two types of authentication:
|
||||
Two different types of authentication are supports:
|
||||
|
||||
- JSON Web Tokens (jwt): This is typically used to authenticate humans in a
|
||||
- **JSON Web Tokens** (jwt): This is typically used to authenticate humans in a
|
||||
browser session.
|
||||
- API Keys (key): This is typically used to interact with the API in an
|
||||
automated way. Like in a script, or a CI/CD context.
|
||||
- **API Keys** (key): This is typically used to interact with the API in an
|
||||
automated way. Like in a script, a CI/CD context, a serverless runner, and so
|
||||
on.
|
||||
|
||||
Apart from the handlful of API endpoints that are accessible without
|
||||
authentication (typically the ones dealing with the signup flow), this API has
|
||||
a variant for each route depending on what authentication you want to use:
|
||||
For each endpoint, the API has a variant depending on what authentication you
|
||||
want to use:
|
||||
|
||||
- `/some/route/jwt` : Authenticate with JWT
|
||||
- `/some/route/key` : Authenticate with an API key and secret
|
||||
|
||||
### JWT authentication
|
||||
|
||||
The use of JSON Web Tokens ([jwt](https://jwt.io)) is typically used in a browser context where we want to establish a *session*.
|
||||
The use of JSON Web Tokens ([jwt](https://jwt.io)) is typically used in a
|
||||
browser context where we want to establish a *session*.
|
||||
|
||||
To get a token, you must first authenticate at the `/login` endpoint with username and password.
|
||||
You will receive a token in the response.
|
||||
To get a token, you must first authenticate at the `/login` endpoint with
|
||||
username and password. You will receive a JSON Web Token (jwt) as part of the
|
||||
response.
|
||||
|
||||
In subsequent API calls, you must then include this token in the `Authorization` header prefixed by `Bearer`. Liek his:
|
||||
In subsequent API calls, you must then include this token in the
|
||||
`Authorization` header prefixed by `Bearer`. Like his:
|
||||
|
||||
```js
|
||||
const account = await axios.get(
|
||||
|
@ -57,11 +63,18 @@ const account = await axios.get(
|
|||
|
||||
### API key authentication
|
||||
|
||||
The combination API key & secret serves as a username & password for HTTP basic authentication.
|
||||
In basic authentication, the password is sent unencrypted, but since the FreeSewing backend is only reachable over a TLS encrypted connection, this is not a problem.
|
||||
The combination of API key & secret serves as a username & password for [HTTP
|
||||
basic authentication](https://en.wikipedia.org/wiki/Basic_access_authentication).
|
||||
|
||||
On the plus side, sending a username and password with a request is supported pretty much everywhere.
|
||||
In addition, there is no need to establish a session first, so this make the entire transation stateless.
|
||||
<Note>
|
||||
In basic authentication, the password is sent
|
||||
unencrypted. To guard against this, this API should only be served over a
|
||||
connectin encrypted with TLS. (a url starting with `https://`).
|
||||
</Note>
|
||||
|
||||
Sending a username and password with a request like this is supported
|
||||
pretty much everywhere. In addition, there is no need to establish a session
|
||||
first, so this make the entire transation stateless.
|
||||
|
||||
Below is an example using curl:
|
||||
|
||||
|
@ -96,8 +109,8 @@ The table below lists the priviledge of all levels as well as their correspondin
|
|||
| `4` | **write all** account data | ✅ | ✅ | ✅ | ✅ |
|
||||
| `5` | **read** measurements or patterns of **other users** | ❌ | ✅ | ✅ | ✅ |
|
||||
| `6` | **read all** account data of **other users** | ❌ | ❌ | ✅ | ✅ |
|
||||
| `7` | **write** access through **specific support methods** | ❌ | ❌ | ✅ | ✅ |
|
||||
| `8` | impersonate other user, full write access | ❌ | ❌ | ❌ | ✅ |
|
||||
| `7` | **write** account data of **other users** through **specific support methods** | ❌ | ❌ | ✅ | ✅ |
|
||||
| `8` | impersonate other users, **full write access** | ❌ | ❌ | ❌ | ✅ |
|
||||
|
||||
## API Routes
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue