diff options
Diffstat (limited to 'doc/md/REST-API.md')
-rw-r--r-- | doc/md/REST-API.md | 100 |
1 files changed, 72 insertions, 28 deletions
diff --git a/doc/md/REST-API.md b/doc/md/REST-API.md index 8f3f7303..0b8aba8a 100644 --- a/doc/md/REST-API.md +++ b/doc/md/REST-API.md | |||
@@ -1,6 +1,18 @@ | |||
1 | ## Usage | 1 | ## Usage and Prerequisites |
2 | 2 | ||
3 | See the [REST API documentation](http://shaarli.github.io/api-documentation/). | 3 | See the [REST API documentation](http://shaarli.github.io/api-documentation/) |
4 | for a list of available endpoints and parameters. | ||
5 | |||
6 | Please ensure that your server meets the [requirements](Server-requirements) | ||
7 | and is properly [configured](Server-configuration): | ||
8 | |||
9 | - URL rewriting is enabled (see specific Apache and Nginx sections) | ||
10 | - the server's timezone is properly defined | ||
11 | - the server's clock is synchronized with | ||
12 | [NTP](https://en.wikipedia.org/wiki/Network_Time_Protocol) | ||
13 | |||
14 | The host where the API client is invoked should also be synchronized with NTP, | ||
15 | see [token expiration](#payload). | ||
4 | 16 | ||
5 | ## Authentication | 17 | ## Authentication |
6 | 18 | ||
@@ -10,10 +22,10 @@ This token has to be included as an HTTP header called `Authentication: Bearer < | |||
10 | 22 | ||
11 | JWT resources : | 23 | JWT resources : |
12 | 24 | ||
13 | * [jwt.io](https://jwt.io) (including a list of client per language). | 25 | - [jwt.io](https://jwt.io) (including a list of client per language). |
14 | * RFC : https://tools.ietf.org/html/rfc7519 | 26 | - RFC : https://tools.ietf.org/html/rfc7519 |
15 | * https://float-middle.com/json-web-tokens-jwt-vs-sessions/ | 27 | - https://float-middle.com/json-web-tokens-jwt-vs-sessions/ |
16 | * HackerNews thread: https://news.ycombinator.com/item?id=11929267 | 28 | - HackerNews thread: https://news.ycombinator.com/item?id=11929267 |
17 | 29 | ||
18 | 30 | ||
19 | ### Shaarli JWT Token | 31 | ### Shaarli JWT Token |
@@ -43,9 +55,11 @@ ewogICAgICAgICJ0eXAiOiAiSldUIiwKICAgICAgICAiYWxnIjogIkhTNTEyIgogICAgfQ== | |||
43 | 55 | ||
44 | #### Payload | 56 | #### Payload |
45 | 57 | ||
46 | **Validity duration** | 58 | **Token expiration** |
47 | 59 | ||
48 | To avoid infinite token validity, JWT tokens must include their creation date in UNIX timestamp format (timezone independant - UTC) under the key `iat` (issued at). This token will be accepted during 9 minutes. | 60 | To avoid infinite token validity, JWT tokens must include their creation date |
61 | in UNIX timestamp format (timezone independent - UTC) under the key `iat` (issued at). | ||
62 | This token will be valid during **9 minutes**. | ||
49 | 63 | ||
50 | ```json | 64 | ```json |
51 | { | 65 | { |
@@ -68,37 +82,67 @@ $signature = hash_hmac('sha512', $content, $secret); | |||
68 | ``` | 82 | ``` |
69 | 83 | ||
70 | 84 | ||
71 | ### Complete example | 85 | ## Clients and examples |
86 | ### Android, Java, Kotlin | ||
87 | |||
88 | - [Android client example with Kotlin](https://gitlab.com/snippets/1665808) | ||
89 | by [Braincoke](https://github.com/Braincoke) | ||
90 | |||
72 | 91 | ||
73 | #### PHP | 92 | ### PHP |
93 | |||
94 | This example uses the [PHP cURL](http://php.net/manual/en/book.curl.php) library. | ||
74 | 95 | ||
75 | ```php | 96 | ```php |
97 | <?php | ||
98 | $baseUrl = 'https://shaarli.mydomain.net'; | ||
99 | $secret = 'thats_my_api_secret'; | ||
100 | |||
101 | function base64url_encode($data) { | ||
102 | return rtrim(strtr(base64_encode($data), '+/', '-_'), '='); | ||
103 | } | ||
104 | |||
76 | function generateToken($secret) { | 105 | function generateToken($secret) { |
77 | $header = base64_encode('{ | 106 | $header = base64url_encode('{ |
78 | "typ": "JWT", | 107 | "typ": "JWT", |
79 | "alg": "HS512" | 108 | "alg": "HS512" |
80 | }'); | 109 | }'); |
81 | $payload = base64_encode('{ | 110 | $payload = base64url_encode('{ |
82 | "iat": '. time() .' | 111 | "iat": '. time() .' |
83 | }'); | 112 | }'); |
84 | $signature = hash_hmac('sha512', $header .'.'. $payload , $secret); | 113 | $signature = base64url_encode(hash_hmac('sha512', $header .'.'. $payload , $secret, true)); |
85 | return $header .'.'. $payload .'.'. $signature; | 114 | return $header . '.' . $payload . '.' . $signature; |
86 | } | 115 | } |
87 | 116 | ||
88 | $secret = 'mysecret'; | ||
89 | $token = generateToken($secret); | ||
90 | echo $token; | ||
91 | ``` | ||
92 | 117 | ||
93 | > `ewogICAgICAgICJ0eXAiOiAiSldUIiwKICAgICAgICAiYWxnIjogIkhTNTEyIgogICAgfQ==.ewogICAgICAgICJpYXQiOiAxNDY4NjY3MDQ3CiAgICB9.1d2c54fa947daf594fdbf7591796195652c8bc63bffad7f6a6db2a41c313f495a542cbfb595acade79e83f3810d709b4251d7b940bbc10b531a6e6134af63a68` | 118 | function getInfo($baseUrl, $secret) { |
119 | $token = generateToken($secret); | ||
120 | $endpoint = rtrim($baseUrl, '/') . '/api/v1/info'; | ||
94 | 121 | ||
95 | ```php | 122 | $headers = [ |
96 | $options = [ | 123 | 'Content-Type: text/plain; charset=UTF-8', |
97 | 'http' => [ | 124 | 'Authorization: Bearer ' . $token, |
98 | 'method' => 'GET', | 125 | ]; |
99 | 'jwt' => $token, | 126 | |
100 | ], | 127 | $ch = curl_init($endpoint); |
101 | ]; | 128 | curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); |
102 | $context = stream_context_create($options); | 129 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); |
103 | file_get_contents($apiEndpoint, false, $context); | 130 | curl_setopt($ch, CURLOPT_AUTOREFERER, 1); |
131 | curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1); | ||
132 | |||
133 | $result = curl_exec($ch); | ||
134 | curl_close($ch); | ||
135 | |||
136 | return $result; | ||
137 | } | ||
138 | |||
139 | var_dump(getInfo($baseUrl, $secret)); | ||
104 | ``` | 140 | ``` |
141 | |||
142 | |||
143 | ### Python | ||
144 | |||
145 | See the reference API client: | ||
146 | |||
147 | - [Documentation](http://python-shaarli-client.readthedocs.io/en/latest/) on ReadTheDocs | ||
148 | - [python-shaarli-client](https://github.com/shaarli/python-shaarli-client) on Github | ||