The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.

Authentication

Auth in aurora is pluggable and opt-in — it is never baked into aurora_app(). aurora ships one scheme: a stateless JWT delivered as an HttpOnly cookie, signed with jose. It stays stateless (the token is self-contained, so any replica can validate it) and is wired entirely in your app’s annotated files.

Scaffold

library(aurora)
aurora_create_app("meu_app", template = "auth")
aurora_run("meu_app")   # log in with admin / admin123

How it is wired

Three pieces, all in the app — aurora_app() needs no auth knowledge:

1. The scheme (a helper). helpers/auth_setup.R defines the scheme and your user lookup:

auth <- aurora_auth_jwt(secret = Sys.getenv("AURORA_JWT_SECRET", "dev-only"))
secure_cookies <- identical(Sys.getenv("AURORA_ENV"), "prod")
find_user <- function(name) ...   # your DB / store; passwords hashed with sodium

2. The gate (a header route). routers/guard.R runs before every /api/* handler — and before the request body is even received — rejecting anyone without a valid token with a clean 401:

#* @any /api/*
#* @header
function(request) {
  aurora_jwt_guard(auth, request)   # 401 via reqres::abort_unauthorized() if invalid
  plumber2::Next                    # otherwise continue the chain
}

3. Public login/logout (not under /api, so the gate ignores them).

#* @post /auth/login
#* @parser json
#* @serializer json
function(request, response, body = NULL) {
  u <- find_user(body$user)
  if (is.null(u) || !sodium::password_verify(u$hash, body$pass %||% "")) {
    response$status <- 401L
    return(list(error = "Usuario ou senha invalidos."))
  }
  token <- aurora_jwt_token(auth, list(user = u$name))
  aurora_set_auth_cookie(auth, response, token, secure = secure_cookies)
  list(user = u$name)
}

#* @post /auth/logout
#* @serializer json
function(response) {
  aurora_clear_auth_cookie(auth, response, secure = secure_cookies)
  list(status = "ok")
}

The frontend

The cookie is HttpOnly, so JavaScript never touches the token. app.js simply probes GET /api/me on load (reveal the app on success), posts to /auth/login / /auth/logout, and shows the login overlay whenever any /api call returns 401 via the runtime’s aurora.onUnauthorized hook.

Helpers

Function Purpose
aurora_auth_jwt(secret, cookie, expiry) define the scheme
aurora_jwt_token(auth, claims) mint a signed token (login)
aurora_jwt_decode(auth, token) verify; returns payload or NULL
aurora_jwt_guard(auth, request) gate: 401 unless valid (use in a @header route)
aurora_set_auth_cookie() / aurora_clear_auth_cookie() manage the cookie

Why not a fireproof guard?

plumber2’s native api_auth_guard() + fireproof guards target upstream identity providers (OAuth/OIDC) or shared static keys, require the firesale datastore plugin, and return 400/403. A self-issued JWT-cookie session needs a uniform 401 for both absent and expired sessions (cookie expiry looks like “absent”) and no extra infrastructure — so aurora uses a @header guard + reqres::abort_unauthorized(), the migration-endorsed replacement for v1 filters.

Production checklist

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.