mirror of
https://github.com/binwiederhier/ntfy.git
synced 2024-12-14 11:47:33 +00:00
Docs for access tokens
This commit is contained in:
parent
355424c0da
commit
70aa384bc3
5 changed files with 227 additions and 12 deletions
|
@ -87,6 +87,11 @@ func WithBasicAuth(user, pass string) PublishOption {
|
|||
return WithHeader("Authorization", util.BasicAuth(user, pass))
|
||||
}
|
||||
|
||||
// WithBearerAuth adds the Authorization header for Bearer auth to the request
|
||||
func WithBearerAuth(token string) PublishOption {
|
||||
return WithHeader("Authorization", fmt.Sprintf("Bearer %s", token))
|
||||
}
|
||||
|
||||
// WithNoCache instructs the server not to cache the message server-side
|
||||
func WithNoCache() PublishOption {
|
||||
return WithHeader("X-Cache", "no")
|
||||
|
|
|
@ -35,6 +35,7 @@ var flagsPublish = append(
|
|||
&cli.StringFlag{Name: "file", Aliases: []string{"f"}, EnvVars: []string{"NTFY_FILE"}, Usage: "file to upload as an attachment"},
|
||||
&cli.StringFlag{Name: "email", Aliases: []string{"mail", "e"}, EnvVars: []string{"NTFY_EMAIL"}, Usage: "also send to e-mail address"},
|
||||
&cli.StringFlag{Name: "user", Aliases: []string{"u"}, EnvVars: []string{"NTFY_USER"}, Usage: "username[:password] used to auth against the server"},
|
||||
&cli.StringFlag{Name: "token", Aliases: []string{"k"}, EnvVars: []string{"NTFY_TOKEN"}, Usage: "access token used to auth against the server"},
|
||||
&cli.IntFlag{Name: "wait-pid", Aliases: []string{"wait_pid", "pid"}, EnvVars: []string{"NTFY_WAIT_PID"}, Usage: "wait until PID exits before publishing"},
|
||||
&cli.BoolFlag{Name: "wait-cmd", Aliases: []string{"wait_cmd", "cmd", "done"}, EnvVars: []string{"NTFY_WAIT_CMD"}, Usage: "run command and wait until it finishes before publishing"},
|
||||
&cli.BoolFlag{Name: "no-cache", Aliases: []string{"no_cache", "C"}, EnvVars: []string{"NTFY_NO_CACHE"}, Usage: "do not cache message server-side"},
|
||||
|
@ -99,10 +100,18 @@ func execPublish(c *cli.Context) error {
|
|||
file := c.String("file")
|
||||
email := c.String("email")
|
||||
user := c.String("user")
|
||||
token := c.String("token")
|
||||
noCache := c.Bool("no-cache")
|
||||
noFirebase := c.Bool("no-firebase")
|
||||
quiet := c.Bool("quiet")
|
||||
pid := c.Int("wait-pid")
|
||||
|
||||
// Checks
|
||||
if user != "" && token != "" {
|
||||
return errors.New("cannot set both --user and --token")
|
||||
}
|
||||
|
||||
// Do the things
|
||||
topic, message, command, err := parseTopicMessageCommand(c)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -144,6 +153,9 @@ func execPublish(c *cli.Context) error {
|
|||
if noFirebase {
|
||||
options = append(options, client.WithNoFirebase())
|
||||
}
|
||||
if token != "" {
|
||||
options = append(options, client.WithBearerAuth(token))
|
||||
}
|
||||
if user != "" {
|
||||
var pass string
|
||||
parts := strings.SplitN(user, ":", 2)
|
||||
|
|
|
@ -222,6 +222,39 @@ User `ben` has three topic-specific entries. He can read, but not write to topic
|
|||
to topic `garagedoor` and all topics starting with the word `alerts` (wildcards). Clients that are not authenticated
|
||||
(called `*`/`everyone`) only have read access to the `announcements` and `server-stats` topics.
|
||||
|
||||
### Access tokens
|
||||
In addition to username/password auth, ntfy also provides authentication via access tokens. Access tokens are useful
|
||||
to avoid having to configure your password across multiple publishing/subscribing applications. For instance, you may
|
||||
want to use a dedicated token to publish from your backup host, and one from your home automation system.
|
||||
|
||||
!!! info
|
||||
As of today, access tokens grant users **full access to the user account**. Aside from changing the password,
|
||||
and deleting the account, every action can be performed with a token. Granular access tokens are on the roadmap,
|
||||
but not yet implemented.
|
||||
|
||||
The `ntfy token` command can be used to manage access tokens for users. Tokens can have labels, and they can expire
|
||||
automatically (or never expire). Each user can have up to 20 tokens (hardcoded).
|
||||
|
||||
**Example commands** (type `ntfy token --help` or `ntfy token COMMAND --help` for more details):
|
||||
```
|
||||
ntfy token list # Shows list of tokens for all users
|
||||
ntfy token list phil # Shows list of tokens for user phil
|
||||
ntfy token add phil # Create token for user phil which never expires
|
||||
ntfy token add --expires=2d phil # Create token for user phil which expires in 2 days
|
||||
ntfy token remove phil tk_th2sxr... # Delete token
|
||||
```
|
||||
|
||||
**Creating an access token:**
|
||||
```
|
||||
$ ntfy token add --expires=30d --label="backups" phil
|
||||
$ ntfy token list
|
||||
user phil
|
||||
- tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2 (backups), expires 15 Mar 23 14:33 EDT, accessed from 0.0.0.0 at 13 Feb 23 13:33 EST
|
||||
```
|
||||
|
||||
Once an access token is created, you can **use it to authenticate against the ntfy server, e.g. when you publish or
|
||||
subscribe to topics**. To learn how, check out [authenticate via access tokens](publish.md#access-tokens).
|
||||
|
||||
### Example: Private instance
|
||||
The easiest way to configure a private instance is to set `auth-default-access` to `deny-all` in the `server.yml`:
|
||||
|
||||
|
|
188
docs/publish.md
188
docs/publish.md
|
@ -2591,23 +2591,22 @@ title `You've Got Mail` to topic `sometopic` (see [ntfy.sh/sometopic](https://nt
|
|||
<figcaption>Publishing a message via e-mail</figcaption>
|
||||
</figure>
|
||||
|
||||
## Advanced features
|
||||
|
||||
### Authentication
|
||||
## Authentication
|
||||
Depending on whether the server is configured to support [access control](config.md#access-control), some topics
|
||||
may be read/write protected so that only users with the correct credentials can subscribe or publish to them.
|
||||
To publish/subscribe to protected topics, you can:
|
||||
|
||||
* Use [basic auth](#basic-auth), e.g. `Authorization: Basic dGVzdHVzZXI6ZmFrZXBhc3N3b3Jk`
|
||||
* or use the [`auth` query parameter](#query-param), e.g. `?auth=QmFzaWMgZEdWemRIVnpaWEk2Wm1GclpYQmhjM04zYjNKaw`
|
||||
* Use [username & password](#username-password) via Basic auth, e.g. `Authorization: Basic dGVzdHVzZXI6ZmFrZXBhc3N3b3Jk`
|
||||
* Use [access tokens](#bearer-auth) via Bearer/Basic auth, e.g. `Authorization: Bearer tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2`
|
||||
* or use either with the [`auth` query parameter](#query-param), e.g. `?auth=QmFzaWMgZEdWemRIVnpaWEk2Wm1GclpYQmhjM04zYjNKaw`
|
||||
|
||||
!!! warning
|
||||
Base64 only encodes username and password. It **is not encrypting it**. For your self-hosted server,
|
||||
**be sure to use HTTPS to avoid eavesdropping** and exposing your password.
|
||||
When using Basic auth, base64 only encodes username and password. It **is not encrypting it**. For your
|
||||
self-hosted server, **be sure to use HTTPS to avoid eavesdropping** and exposing your password.
|
||||
|
||||
#### Basic auth
|
||||
Here's an example using [Basic auth](https://en.wikipedia.org/wiki/Basic_access_authentication), with a user `testuser`
|
||||
and password `fakepassword`:
|
||||
### Username & password
|
||||
The simplest way to authenticate against a ntfy server is to use [Basic auth](https://en.wikipedia.org/wiki/Basic_access_authentication).
|
||||
Here's an example with a user `testuser` and password `fakepassword`:
|
||||
|
||||
=== "Command line (curl)"
|
||||
```
|
||||
|
@ -2701,7 +2700,172 @@ The following command will generate the appropriate value for you on *nix system
|
|||
echo "Basic $(echo -n 'testuser:fakepassword' | base64)"
|
||||
```
|
||||
|
||||
#### Query param
|
||||
### Access tokens
|
||||
In addition to username/password auth, ntfy also provides authentication via access tokens. Access tokens are useful
|
||||
to avoid having to configure your password across multiple publishing/subscribing applications. For instance, you may
|
||||
want to use a dedicated token to publish from your backup host, and one from your home automation system.
|
||||
|
||||
You can create access tokens using the `ntfy token` command, or in the web app in the "Account" section (when logged in).
|
||||
See [access tokens](config.md#access-tokens) for details.
|
||||
|
||||
Once an access token is created, you can use it to authenticate against the ntfy server, e.g. when you publish or
|
||||
subscribe to topics. Here's an example using [Bearer auth](https://swagger.io/docs/specification/authentication/bearer-authentication/),
|
||||
with the token `tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2`:
|
||||
|
||||
=== "Command line (curl)"
|
||||
```
|
||||
curl \
|
||||
-H "Authorization: Bearer tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2" \
|
||||
-d "Look ma, with auth" \
|
||||
https://ntfy.example.com/mysecrets
|
||||
```
|
||||
|
||||
=== "ntfy CLI"
|
||||
```
|
||||
ntfy publish \
|
||||
--token tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2 \
|
||||
ntfy.example.com/mysecrets \
|
||||
"Look ma, with auth"
|
||||
```
|
||||
|
||||
=== "HTTP"
|
||||
``` http
|
||||
POST /mysecrets HTTP/1.1
|
||||
Host: ntfy.example.com
|
||||
Authorization: Bearer tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2
|
||||
|
||||
Look ma, with auth
|
||||
```
|
||||
|
||||
=== "JavaScript"
|
||||
``` javascript
|
||||
fetch('https://ntfy.example.com/mysecrets', {
|
||||
method: 'POST', // PUT works too
|
||||
body: 'Look ma, with auth',
|
||||
headers: {
|
||||
'Authorization': 'Bearer tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2'
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
=== "Go"
|
||||
``` go
|
||||
req, _ := http.NewRequest("POST", "https://ntfy.example.com/mysecrets",
|
||||
strings.NewReader("Look ma, with auth"))
|
||||
req.Header.Set("Authorization", "Bearer tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2")
|
||||
http.DefaultClient.Do(req)
|
||||
```
|
||||
|
||||
=== "PowerShell"
|
||||
``` powershell
|
||||
$uri = "https://ntfy.example.com/mysecrets"
|
||||
$headers = @{Authorization="Bearer tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2"}
|
||||
$message = "Look ma, with auth"
|
||||
Invoke-RestMethod -Uri $uri -Body $message -Headers $headers -Method "Post" -UseBasicParsing
|
||||
```
|
||||
|
||||
=== "Python"
|
||||
``` python
|
||||
requests.post("https://ntfy.example.com/mysecrets",
|
||||
data="Look ma, with auth",
|
||||
headers={
|
||||
"Authorization": "Bearer tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2"
|
||||
})
|
||||
```
|
||||
|
||||
=== "PHP"
|
||||
``` php-inline
|
||||
file_get_contents('https://ntfy.example.com/mysecrets', false, stream_context_create([
|
||||
'http' => [
|
||||
'method' => 'POST', // PUT also works
|
||||
'header' =>
|
||||
'Content-Type: text/plain\r\n' .
|
||||
'Authorization: Bearer tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2',
|
||||
'content' => 'Look ma, with auth'
|
||||
]
|
||||
]));
|
||||
```
|
||||
|
||||
Alternatively, you can use [Basic Auth](https://en.wikipedia.org/wiki/Basic_access_authentication) to send the
|
||||
access token. When sending an empty username, the basic auth password is treated by the ntfy server as an
|
||||
access token. This is primarily useful to make `curl` calls easier, e.g. `curl -u:tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2 ...`:
|
||||
|
||||
=== "Command line (curl)"
|
||||
```
|
||||
curl \
|
||||
-u :tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2 \
|
||||
-d "Look ma, with auth" \
|
||||
https://ntfy.example.com/mysecrets
|
||||
```
|
||||
|
||||
=== "ntfy CLI"
|
||||
```
|
||||
ntfy publish \
|
||||
--token tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2 \
|
||||
ntfy.example.com/mysecrets \
|
||||
"Look ma, with auth"
|
||||
```
|
||||
|
||||
=== "HTTP"
|
||||
``` http
|
||||
POST /mysecrets HTTP/1.1
|
||||
Host: ntfy.example.com
|
||||
Authorization: Basic OnRrX0FnUWRxN21WQm9GRDM3elFWTjI5Umh1TXpOSXoy
|
||||
|
||||
Look ma, with auth
|
||||
```
|
||||
|
||||
=== "JavaScript"
|
||||
``` javascript
|
||||
fetch('https://ntfy.example.com/mysecrets', {
|
||||
method: 'POST', // PUT works too
|
||||
body: 'Look ma, with auth',
|
||||
headers: {
|
||||
'Authorization': 'Basic OnRrX0FnUWRxN21WQm9GRDM3elFWTjI5Umh1TXpOSXoy'
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
=== "Go"
|
||||
``` go
|
||||
req, _ := http.NewRequest("POST", "https://ntfy.example.com/mysecrets",
|
||||
strings.NewReader("Look ma, with auth"))
|
||||
req.Header.Set("Authorization", "Basic OnRrX0FnUWRxN21WQm9GRDM3elFWTjI5Umh1TXpOSXoy")
|
||||
http.DefaultClient.Do(req)
|
||||
```
|
||||
|
||||
=== "PowerShell"
|
||||
``` powershell
|
||||
$uri = "https://ntfy.example.com/mysecrets"
|
||||
$headers = @{Authorization="Basic OnRrX0FnUWRxN21WQm9GRDM3elFWTjI5Umh1TXpOSXoy"}
|
||||
$message = "Look ma, with auth"
|
||||
Invoke-RestMethod -Uri $uri -Body $message -Headers $headers -Method "Post" -UseBasicParsing
|
||||
```
|
||||
|
||||
=== "Python"
|
||||
``` python
|
||||
requests.post("https://ntfy.example.com/mysecrets",
|
||||
data="Look ma, with auth",
|
||||
headers={
|
||||
"Authorization": "Basic OnRrX0FnUWRxN21WQm9GRDM3elFWTjI5Umh1TXpOSXoy"
|
||||
})
|
||||
```
|
||||
|
||||
=== "PHP"
|
||||
``` php-inline
|
||||
file_get_contents('https://ntfy.example.com/mysecrets', false, stream_context_create([
|
||||
'http' => [
|
||||
'method' => 'POST', // PUT also works
|
||||
'header' =>
|
||||
'Content-Type: text/plain\r\n' .
|
||||
'Authorization: Basic OnRrX0FnUWRxN21WQm9GRDM3elFWTjI5Umh1TXpOSXoy',
|
||||
'content' => 'Look ma, with auth'
|
||||
]
|
||||
]));
|
||||
```
|
||||
|
||||
|
||||
### Query param
|
||||
Here's an example using the `auth` query parameter:
|
||||
|
||||
=== "Command line (curl)"
|
||||
|
@ -2786,6 +2950,8 @@ The following command will generate the appropriate value for you on *nix system
|
|||
echo -n "Basic `echo -n 'testuser:fakepassword' | base64`" | base64 | tr -d '='
|
||||
```
|
||||
|
||||
## Advanced features
|
||||
|
||||
### Message caching
|
||||
!!! info
|
||||
If `Cache: no` is used, messages will only be delivered to connected subscribers, and won't be re-delivered if a
|
||||
|
|
|
@ -38,7 +38,6 @@ import (
|
|||
- HIGH Docs
|
||||
- tiers
|
||||
- api
|
||||
- tokens
|
||||
|
||||
*/
|
||||
|
||||
|
|
Loading…
Reference in a new issue