alpacon
Authentication

Authentication

Alpacon provides several methods to authenticate users and client machines.

Session authentication

Session authentication is the most basic one, and you can use it for users to sign in on web browsers.

On login, POST should include username, password, and csrf_token. A serialized HTML form with proper fields is accepted.

Login information is set using the session cookies. Please be aware to preserve the cookie and use it for future API access. As Django session authentication requires CSRF protection, you need to include CSRF token if you are using unsafe methods like POST, PUT, PATCH, or DELETE. (Only when using session authentication!)

Following example shows setting CSRF token to HTTP header when using jquery ajax.

import Cookies from "js-cookie";
 
function csrfSafeMethod(method) {
  // these HTTP methods do not require CSRF protection
  return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
 
$.ajaxSetup({
  beforeSend: function(xhr, settings) {
      if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
          xhr.setRequestHeader("X-CSRFToken", Cookies.get('csrftoken'));
      }
  }
});
 
window.Cookies = Cookies;

References

  1. https://docs.djangoproject.com/en/4.0/ref/csrf/#ajax (opens in a new tab)

API token authentication

API token is used to authenticate users in applications—for example, Alpacon React.

Upon successful login, the Alpacon Server issues an API token, which is then used to authorize subsequent API requests.

Login

Post username and password to /api/auth/login/.

  • HTTP method: POST
  • Accepted formats: application/json, application/x-www-form-urlencoded, multipart/form-data
  • Request data: username, password
  • Response data: {"token": "xxxxxx", "expires_at": "oooooo"}. Token is a random string with 128 characters.
  • Status codes: 200 OK on success, 403 Forbidden on failure.

The returned token will be valid for 14 days from the last access. Upon the expiry date, any further API access will result in 403 Forbidden.

Using the token

After obtaining the token, include it in the HTTP header on every further request.

  • HTTP header: Authorization: token="xxxxx"

Please make sure to include "" as well.

Check authenticated

Applications can check the authentication status at /api/auth/is_authenticated/.

  • HTTP method: GET
  • Response data: {"authenticated": true or false}
  • Status codes: 200 OK regardless of authentication status.

This interface should always return 200 OK.

Logout

Logout the current user at /api/auth/logout/. Please make sure to include the token in the HTTP header just like other requests.

  • HTTP methods: GET, POST (both works fine.)
  • Request data: null
  • Response data: null
  • Status codes: 200 OK on success, 403 Forbidden on failure. (possibly if not authenticated.)

Token validation

The application must check the status code of each API request to verify token validity. If the token is invalid, the Alpacon Server responds with a 403 Forbidden error.

Login sessions

APIs are provided to list and revoke active login sessions for the current user.

Listing login sessions

You can retrieve the list of all login sessions associated with the user.

Request:

GET /api/auth/sessions/

Response:

HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
    "count": 2,
    "next": null,
    "previous": null,
    "results": [
        {
            "id": "c0254139-5861-49cc-b5e3-a19e6ceb8c93",
            "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36",
            "remote_ip": "127.0.0.1",
            "added_at": "2022-11-28T16:57:43.599180+09:00",
            "expires_at": "2022-12-05T16:57:43.599020+09:00"
        },
        {
            "id": "7392bed1-038f-4cfb-9814-0f79e0d90021",
            "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36",
            "remote_ip": "127.0.0.1",
            "added_at": "2022-11-28T16:56:10.830929+09:00",
            "expires_at": "2022-12-05T16:56:10.830650+09:00"
        }
    ]
}

Revoking login sessions

If you delete a session, the session will be revoked and user will be signed out automatically.

Request:

DELETE /api/auth/sessions/<id>/

API tokens

API tokens can be used to access alpacon by a program.

Creating an API token

You can create an API token with name and expires_at data. Please note that expires_at can be null. In this case, the token will never expire.

Request:

POST /api/auth/tokens/
{
    "name": "test",
    "expires_at": "2022-11-30T00:00:00+09:00"
}

Response:

HTTP 201 Created
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
    "id": "ff2be1a8-1ae1-4570-9af8-9a21eec4ad22",
    "name": "test",
    "key": "tXaiFo8ltylL877mYhauNBCf2yDsn3kLD2soSeG4PPGF9hfr2cadOyPEofpnDdcW",
    "enabled": true,
    "updated_at": "2022-11-28T18:01:46.966094+09:00",
    "expires_at": null
}

You can use above key as a token for alpacon.

Listing API tokens

You can obtain the list of all API tokens for the user.

Request:

GET /api/auth/tokens/

Response:

HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
    "count": 29,
    "next": "http://localhost:8000/api/auth/tokens/?page=2",
    "previous": null,
    "results": [
        {
            "id": "3ce230e4-7cfb-427f-897c-3a98d65482bc",
            "name": "test",
            "enabled": true,
            "updated_at": "2022-11-28T15:54:52.429589+09:00",
            "expires_at": null
        },
        {
            "id": "2c9b43bc-e98b-47e6-b7ec-b34b8c00f48c",
            "name": "hello",
            "enabled": true,
            "updated_at": "2022-11-28T15:53:37.430753+09:00",
            "expires_at": null
        },
        ...
    ]
}

Updating metadata

You can update the name, enabled, and expires_at fields.

Request:

PATCH /api/auth/tokens/3ce230e4-7cfb-427f-897c-3a98d65482bc/
{
    "name": "test",
    "enabled": true,
    "expires_at": null
}

Deleting an API token

You can delete an API token if it is no longer needed.

Request:

DELETE /api/auth/tokens/3ce230e4-7cfb-427f-897c-3a98d65482bc/

Password Management

Password change

You can change account passwords in two ways.

Changing password for your own account

You can change your password via /api/auth/change_password/.

  • HTTP method: POST
  • Request data: password, new_password
  • Response data: null
  • Status codes: 200 OK on success, 400 Bad request on failure, 403 Forbidden if unauthenticated.

This interface validates the correctness of current password for security. The new_password should satisfy the password security requirements. If any of these checks fail, 400 Bad request will be returned and errors will be set.

After successful change, all active sessions will be revoked (signed out) but tokens will remain valid.

Changing passwords for all user accounts (superuser only)

Admin can change the passwords of all user accounts via /api/users/users/<slug:username>/.

  • HTTP method: PUT, PATCH
  • Request data: password
  • Response data: User object
  • Status codes: 200 OK on success, 400 Bad request on failure.

This interface does not validate the correctness of current password, and is available only to superusers. The new password should still satisfy the password security requirements as /api/auth/change_password/ does.

Password reset

Users can request password reset if they forgot their passwords via /api/auth/reset_password/.

Request:

POST /api/auth/reset_password/
{
    "email": "example@example.com"
}

If the request is successful, a password reset link will be sent to the provided email address. Users can then reset their password again using the link.

Please note that a user can make 5 pending reset requests at max. It this limit is exceeded, the server will return a 403 Forbidden response.

This interface will be rate-limited to prevent abuse. email should be a registered once. To prevent attackers from probing for valid email addresses, the server will not return 400 Bad request even if the email is not registered. Instead, invalid requests will be silently ignored without any error message.

Password reset confirmation

The confirmation link for resetting a password will look like the following:

http://localhost:8000/api/auth/reset_password/confirm/WFVzTuCywZfNJQVNoBCgAgvr4FGojkQ9dKnrK0sQiugSiIwpjfONpeSUjueVchLH/

The last part of the URL WFVzTuCywZfNJQVNoBCgAgvr4FGojkQ9dKnrK0sQiugSiIwpjfONpeSUjueVchLH is the confirmation key.

Upon successful GET request, the API server will redirect the user to the alpacon-react. The alpacon-react should handle this URL and display a password reset interface.

If user enters new password, send a POST request to the server.

POST /api/auth/reset_password/confirm/WFVzTuCywZfNJQVNoBCgAgvr4FGojkQ9dKnrK0sQiugSiIwpjfONpeSUjueVchLH/
{
    "new_password": ""
}

The password will be changed and all pending reset requests for the user will be invalidated. All open sessions for the user will be signed out.