diff options
author | nodiscc <nodiscc@gmail.com> | 2020-05-16 12:54:51 +0200 |
---|---|---|
committer | nodiscc <nodiscc@gmail.com> | 2020-09-12 14:31:45 +0200 |
commit | 91a21c272960889afd4eaa431a3d29b7785b6efc (patch) | |
tree | 26e3ba62319964c5fd48d93fdfe47813d5dc9bf5 /doc/md/REST-API.md | |
parent | 6128ab6a55430a2b705be31ff417c0c552a0db1f (diff) | |
download | Shaarli-91a21c272960889afd4eaa431a3d29b7785b6efc.tar.gz Shaarli-91a21c272960889afd4eaa431a3d29b7785b6efc.tar.zst Shaarli-91a21c272960889afd4eaa431a3d29b7785b6efc.zip |
**General rewording, proof-reading, deduplication, shortening, reordering, simplification, cleanup/formatting/standardization**
- standardize page names, rework documentation structure, update TOC
- use same example paths everywhere
- level 1 titles on all pages
- fix broken links
- .md suffix on all page links (works both from readthedocs and github repository views)
**Server:**
A full and concise installation guide with examples is a frequent request. The documentation should provide such a guide for basic installation needs, while explaining alternative/advanced configuration at the end. Links to reference guides and documentation should be used more frequently to avoid recommending an outdated or excessively complex configuration.
- server: move most server-related info to server-configuration.md, cleanup/shorten
- server: update list of php dependencies/libraries, link to composer.json
- server: installation: support 3 install methods (from release zip, from sources, using docker)
- server: installation: use rsync instead of mv as mv results will change depending of taget directory already existing or not
- server: add example/basic usage of certbot
- server, upgrade, installation: update file permissions setup, use sudo for upgrade operations in webserver document root
- server: apache: add comments to configuration, fix and factorize file permissions setup, set cache-control header, deny access to dotfiles, add missing apache config steps, add http->https redirect example
- server: nginx: refactor nginx configuration, add comments, DO log access to denied/protected files
- server: add links to MDN for x-forwarded-* http headers explanation, cleanup/clarify robots.txt and crawlers section
- server: bump file upload size limit to 100MB we have reports of bookmark exports weighing +40MB - i have a 13MB one here
- server: simplify phpinfo documentation
- server: move backup and restore information to dedicated page
- docker: move all docker docs to Docker.md, simplify/ docker setup, add docker-compose.yml example, replace docker-101 with docker cheatsheet
- troubleshooting: move all troubleshooting documentation to troubleshooting.md
**Usage:**
- index: add getting started section on index page
- features/usage: move all usage-related documentation to usage.md, add links from the main feature list to corresponding usage docs, clarify/reword features list
- shaarli configuration: add note about configuring from web interface
**Removed:**
- remove obsolete/orphan images
- remove obsolete shaarchiver example
- remove outdated "decode datastore content" snippet
**Development:**
- development: move development-related docs (static analysis, CI, unit tests, 3rd party libs, link structure/directory, guidelines, security....) to dev/ directory
- development: Merge several pages to development.md
- **Breaking change?:** remove mentions of 'stable' branch, switch to new branch/release model (master=latest commit, release=latest tag)
- **Breaking change?:** refer to base sharing unit as "Shaare" everywhere (TODO: reflect changes in the code?) doc: update featues list/link to usage.md for details
- development: directory structure: add note about required file permissions
- .travis-ci.yml: add comments
- .htaccess: add comment
Diffstat (limited to 'doc/md/REST-API.md')
-rw-r--r-- | doc/md/REST-API.md | 159 |
1 files changed, 68 insertions, 91 deletions
diff --git a/doc/md/REST-API.md b/doc/md/REST-API.md index 11bd1cd2..01071d8e 100644 --- a/doc/md/REST-API.md +++ b/doc/md/REST-API.md | |||
@@ -1,101 +1,24 @@ | |||
1 | ## Usage and Prerequisites | 1 | # REST API |
2 | 2 | ||
3 | See the [REST API documentation](http://shaarli.github.io/api-documentation/) | 3 | ## Server requirements |
4 | for a list of available endpoints and parameters. | ||
5 | 4 | ||
6 | Please ensure that your server meets the | 5 | See the **[REST API documentation](http://shaarli.github.io/api-documentation/)** for a list of available endpoints and parameters. |
7 | [requirements](Server-configuration#prerequisites) and is properly | 6 | |
8 | [configured](Server-configuration): | 7 | Please ensure that your server meets the requirements and is properly [configured](Server-configuration): |
9 | 8 | ||
10 | - URL rewriting is enabled (see specific Apache and Nginx sections) | 9 | - URL rewriting is enabled (see specific Apache and Nginx sections) |
11 | - the server's timezone is properly defined | 10 | - the server's timezone is properly defined |
12 | - the server's clock is synchronized with | 11 | - the server's clock is synchronized with [NTP](https://en.wikipedia.org/wiki/Network_Time_Protocol) |
13 | [NTP](https://en.wikipedia.org/wiki/Network_Time_Protocol) | ||
14 | |||
15 | The host where the API client is invoked should also be synchronized with NTP, | ||
16 | see [token expiration](#payload). | ||
17 | |||
18 | ## Authentication | ||
19 | |||
20 | All requests to Shaarli's API must include a JWT token to verify their authenticity. | ||
21 | |||
22 | This token has to be included as an HTTP header called `Authentication: Bearer <jwt token>`. | ||
23 | |||
24 | JWT resources : | ||
25 | |||
26 | - [jwt.io](https://jwt.io) (including a list of client per language). | ||
27 | - RFC : https://tools.ietf.org/html/rfc7519 | ||
28 | - https://float-middle.com/json-web-tokens-jwt-vs-sessions/ | ||
29 | - HackerNews thread: https://news.ycombinator.com/item?id=11929267 | ||
30 | |||
31 | |||
32 | ### Shaarli JWT Token | ||
33 | |||
34 | JWT tokens are composed by three parts, separated by a dot `.` and encoded in base64: | ||
35 | |||
36 | ``` | ||
37 | [header].[payload].[signature] | ||
38 | ``` | ||
39 | |||
40 | #### Header | ||
41 | |||
42 | Shaarli only allow one hash algorithm, so the header will always be the same: | ||
43 | |||
44 | ```json | ||
45 | { | ||
46 | "typ": "JWT", | ||
47 | "alg": "HS512" | ||
48 | } | ||
49 | ``` | ||
50 | |||
51 | Encoded in base64, it gives: | ||
52 | |||
53 | ``` | ||
54 | ewogICAgICAgICJ0eXAiOiAiSldUIiwKICAgICAgICAiYWxnIjogIkhTNTEyIgogICAgfQ== | ||
55 | ``` | ||
56 | |||
57 | #### Payload | ||
58 | |||
59 | **Token expiration** | ||
60 | |||
61 | To avoid infinite token validity, JWT tokens must include their creation date | ||
62 | in UNIX timestamp format (timezone independent - UTC) under the key `iat` (issued at). | ||
63 | This token will be valid during **9 minutes**. | ||
64 | |||
65 | ```json | ||
66 | { | ||
67 | "iat": 1468663519 | ||
68 | } | ||
69 | ``` | ||
70 | |||
71 | See [RFC reference](https://tools.ietf.org/html/rfc7519#section-4.1.6). | ||
72 | |||
73 | 12 | ||
74 | #### Signature | 13 | The host where the API client is invoked should also be synchronized with NTP, see _payload/token expiration_ |
75 | |||
76 | The signature authenticate the token validity. It contains the base64 of the header and the body, separated by a dot `.`, hashed in SHA512 with the API secret available in Shaarli administration page. | ||
77 | |||
78 | Signature example with PHP: | ||
79 | |||
80 | ```php | ||
81 | $content = base64_encode($header) . '.' . base64_encode($payload); | ||
82 | $signature = hash_hmac('sha512', $content, $secret); | ||
83 | ``` | ||
84 | 14 | ||
85 | 15 | ||
86 | ## Clients and examples | 16 | ## Clients and examples |
87 | ### Android, Java, Kotlin | ||
88 | |||
89 | - [Android client example with Kotlin](https://gitlab.com/snippets/1665808) | ||
90 | by [Braincoke](https://github.com/Braincoke) | ||
91 | |||
92 | ### Javascript, NodeJS | ||
93 | 17 | ||
94 | - [shaarli-client](https://www.npmjs.com/package/shaarli-client) | 18 | - **[python-shaarli-client](https://github.com/shaarli/python-shaarli-client)** - the reference API client ([Documentation](http://python-shaarli-client.readthedocs.io/en/latest/)) |
95 | ([source code](https://github.com/laBecasse/shaarli-client)) | 19 | - [shaarli-client](https://www.npmjs.com/package/shaarli-client) - NodeJs client ([source code](https://github.com/laBecasse/shaarli-client)) by [laBecasse](https://github.com/laBecasse) |
96 | by [laBecasse](https://github.com/laBecasse) | 20 | - [Android client example with Kotlin](https://gitlab.com/snippets/1665808) by [Braincoke](https://github.com/Braincoke) |
97 | 21 | ||
98 | ### PHP | ||
99 | 22 | ||
100 | This example uses the [PHP cURL](http://php.net/manual/en/book.curl.php) library. | 23 | This example uses the [PHP cURL](http://php.net/manual/en/book.curl.php) library. |
101 | 24 | ||
@@ -145,13 +68,57 @@ function getInfo($baseUrl, $secret) { | |||
145 | var_dump(getInfo($baseUrl, $secret)); | 68 | var_dump(getInfo($baseUrl, $secret)); |
146 | ``` | 69 | ``` |
147 | 70 | ||
71 | ## Implementation | ||
72 | |||
73 | ### Authentication | ||
74 | |||
75 | - All requests to Shaarli's API must include a **JWT token** to verify their authenticity. | ||
76 | - This token must be included as an HTTP header called `Authentication: Bearer <jwt token>`. | ||
77 | - JWT tokens are composed by three parts, separated by a dot `.` and encoded in base64: | ||
78 | |||
79 | ``` | ||
80 | [header].[payload].[signature] | ||
81 | ``` | ||
82 | |||
83 | ##### Header | ||
84 | |||
85 | Shaarli only allow one hash algorithm, so the header will always be the same: | ||
86 | |||
87 | ```json | ||
88 | { | ||
89 | "typ": "JWT", | ||
90 | "alg": "HS512" | ||
91 | } | ||
92 | ``` | ||
93 | |||
94 | Encoded in base64, it gives: | ||
148 | 95 | ||
149 | ### Python | 96 | ``` |
97 | ewogICAgICAgICJ0eXAiOiAiSldUIiwKICAgICAgICAiYWxnIjogIkhTNTEyIgogICAgfQ== | ||
98 | ``` | ||
99 | |||
100 | ##### Payload | ||
101 | |||
102 | Token expiration: To avoid infinite token validity, JWT tokens must include their creation date in UNIX timestamp format (timezone independent - UTC) under the key `iat` (issued at) field ([1](https://tools.ietf.org/html/rfc7519#section-4.1.6)). This token will be valid during **9 minutes**. | ||
103 | |||
104 | ```json | ||
105 | { | ||
106 | "iat": 1468663519 | ||
107 | } | ||
108 | ``` | ||
109 | |||
110 | ##### Signature | ||
111 | |||
112 | The signature authenticates the token validity. It contains the base64 of the header and the body, separated by a dot `.`, hashed in SHA512 with the API secret available in Shaarli administration page. | ||
113 | |||
114 | Example signature with PHP: | ||
115 | |||
116 | ```php | ||
117 | $content = base64_encode($header) . '.' . base64_encode($payload); | ||
118 | $signature = hash_hmac('sha512', $content, $secret); | ||
119 | ``` | ||
150 | 120 | ||
151 | See the reference API client: | ||
152 | 121 | ||
153 | - [Documentation](http://python-shaarli-client.readthedocs.io/en/latest/) on ReadTheDocs | ||
154 | - [python-shaarli-client](https://github.com/shaarli/python-shaarli-client) on Github | ||
155 | 122 | ||
156 | ## Troubleshooting | 123 | ## Troubleshooting |
157 | 124 | ||
@@ -171,3 +138,13 @@ to get the actual error message in the HTTP response body with: | |||
171 | } | 138 | } |
172 | } | 139 | } |
173 | ``` | 140 | ``` |
141 | |||
142 | ## References | ||
143 | |||
144 | - [jwt.io](https://jwt.io) (including a list of client per language). | ||
145 | - [RFC - JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) | ||
146 | - [JSON Web Tokens (JWT) vs Sessions](https://float-middle.com/json-web-tokens-jwt-vs-sessions/), [HackerNews thread](https://news.ycombinator.com/item?id=11929267) | ||
147 | |||
148 | |||
149 | |||
150 | |||