# Authentication

Going back to these snippets of [the configuration file](/ws4sqlite/v0.14-devel/documentation/configuration-file.md):

```yaml
[...]
    auth:
      mode: HTTP
      customErrorCode: 499
      byCredentials:
        - user: myUser1
          password: myCoolPassword
        - user: myUser2
          hashedPassword: b133a0c0e9bee3be20163d2ad31d6248db292aa6dcb1ee087a2aa50e0fc75a[e2
 [...]
    auth:
      mode: INLINE
      byQuery: SELECT 1 FROM AUTH WHERE USER = :user AND PASSWORD = :password
```

The `auth`nodes represent the structure that instructs ws4sqlite to protect that db with authentication.

{% hint style="info" %}
If a database is protected with auth and the client provides wrong credentials, or doesn't provide any, the HTTP answer will be `401 Unauthorised`.
{% endhint %}

### On the server

#### Authentication `mode`

*Lines 3, 12; string; mandatory*

The first, common parameter is `mode`, that indicates the means that the client is required to use to authenticate. It can be:

* `HTTP`: the client needs to use [HTTP basic authentication](https://it.wikipedia.org/wiki/Basic_access_authentication);
* `INLINE`: the credentials needs to be specified in the JSON request. See [below](#on-the-client).

#### Custom error code

*Line 4; number*

If this parameter is not specified, an authentication error will return the standard `401 Not Authorized`. Often a browser will react to this by displaying a standard authentication dialog; if this is not desired (because the auth has a custom implementation, for example) it may be needed to specify an alternative error code. The `customErrorCode` configuration allows to do exactly this.

#### Specifying the credentials

*Lines 5-9, 13; object; mandatory*

You can see that there are two methods to configure the resolution of the credentials on the server:

* Provide a query that will be executed in the database, as in Line 13.\
  \
  The query SQL must contain two placeholders, `:user` and `:password`, that will be replaced by the server with the username and password provided by the client.\
  \
  If the query returns at least one result, the credentials are valid; if it returns 0 records, access will be denied.\\
* Provide a set of credentials in the config file itself, as in Lines 6-9.\
  \
  You can specify the password as plain text (ensure that the file is not world-readable...) or as SHA-256 hashes. See [below](#generating-the-token) to learn how to hash passwords.

The `auth` block is not mandatory. If provided, the database will be protected with it; if omitted, no authentication is requested. If you provide one, it will be ignored.

{% hint style="danger" %}
The password are passed in cleartext, so it is better to be on a protected connection like HTTPS (e.g. by using a reverse proxy). See the [security](/ws4sqlite/v0.14-devel/security.md#authentication) page for further information.
{% endhint %}

#### Generating hashes

{% hint style="warning" %}
Be careful not to include any whitespace in the text to hash, including any carriage return. If using `echo` it's better to specify the `-n` flag.
{% endhint %}

In order to generate hashes for the password, you can use an online service like [this](https://emn178.github.io/online-tools/sha256.html), but it's better not to trust anything online. In Linux or MacOS you can instead use this one-liner:

```bash
read -p Key: -rs ws4s_token && echo && echo -n $ws4s_token | shasum -a 256 -|head -c 64 && echo && ws4s_token=
```

This will read a string from the stdin without echoing it, and outputs the hash to use.

### Credentials in the request (`INLINE` mode)

When a database is protected with authentication in [`INLINE` mode](#mode), the client needs to specify the credentials in the request itself. Simply include a node like this:

```json
{
    "credentials": {
        "user": "myUser1",
        "password": "myCoolPassword"
    },
    [...]
```

If the token verification fails, the response will be returned after 1 second, to prevent brute forcing. The wait time is per database: different failed requests for the same database will "stack", while different databases will work concurrently.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://germ.gitbook.io/ws4sqlite/v0.14-devel/documentation/authentication.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
