diff --git a/.gitignore b/.gitignore index 60ba17a..a1ef8de 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ **/test/clients/ **/test/server/ +docs_build/ .DS_Store \ No newline at end of file diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 0000000..5d6a32e --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,3 @@ +version: 2 +mkdocs: + configuration: mkdocs.yml diff --git a/README.md b/README.md index 4ce7d15..1716d6a 100644 --- a/README.md +++ b/README.md @@ -48,410 +48,5 @@ Access the frontend at: http://localhost:8080 To access the Mailhog frontend and check for your signup mail: http://localhost:8025 -## Setup -Prerequisites: A MongoDB instance (tested with MongoDB v4). - -Please refer to the [docker-compose.yml](https://github.com/virtualzone/jwt-auth-proxy/blob/master/example/docker-compose.yml) example on how to use the pre-build Docker image. - -The server requires a key and a certificate for providing mTLS encryption for the backend REST API. - -You can generate the server's and clients' keys and certificates manually using OpenSSL. By default, the server will create a CA and generate keys and certificates for both server and client on startup (see BACKEND_GENERATE_CERT environment variable). - -## Handling proxied requests in your application's backend -When your application's backend receives an HTTP request proxied through the JWT Auth Proxy, it receives all the HTTP request headers sent by the HTTP client/browser, plus: - -* ```Authorization```: The successfully validated JWT access token (format: ```Bearer ```). -* ```X-Auth-UserID```: The user's ID you can use to make calls to the backend-facing REST API. -* ```Forwarded```: Information from the client-facing side of the proxy server. -* ```X-Forwarded-For``` (XFF): The originating IP address of the client. -* ```X-Forwarded-Host``` (XFH): The original host requested by the client in the Host HTTP request header. -* ```X-Forwarded-Proto``` (XFP): The protocol (HTTP or HTTPS) the client used to connect to the proxy. - -## User-facing REST API -### Sign up / register new user -* Use Case: Sign up a new user using his unique email address as the username. -* URL: /auth/signup -* Method: POST -* JSON Payload: - ``` - { - "email": "", - "password": "" - } - ``` -* HTTP Response Status Codes: - * 201: Created (user successfully signed up, User ID in response header 'X-Object-ID') - * 400: Bad request (invalid JSON payload) - * 409: Conflict (user already exists) - -### Log in -* Use case: Log in an activated and enabled user, retrieve Access and Refresh Tokens. -* URL: /auth/login -* Method: POST -* JSON Payload: - ``` - { - "email": "", - "password": "", - "otp": "" - } - ``` -* HTTP Response Status Codes: - * 200: OK (user successfully logged in or additional TOTP required, result in response body payload) - * 400: Bad request (invalid JSON payload) - * 401: Unauthorized (authorization failed due to various reasons) -* HTTP Response Body for successful login: - ``` - { - "accessToken": "", - "refreshToken": "", - } - ``` -* HTTP Response Body if TOTP is required: - ``` - { - "otpRequired": true - } - ``` - -### Refresh Access Token -* Use case: Refresh short-lived Access Token with long-lived Refresh Token. -* URL: /auth/refresh -* Method: POST -* Request Header: ```Authorization: Bearer ``` -* JSON Payload: - ``` - { - "refreshToken": "" - } - ``` -* HTTP Response Status Codes: - * 200: OK (successful, result in response body payload) - * 400: Bad request (invalid JSON payload) - * 401: Unauthorized (authorization failed due to various reasons) -* HTTP Response Body: - ``` - { - "accessToken": "", - "refreshToken": "", - } - ``` - -### Log out -* Use case: Invalidate Refresh Token. -* URL: /auth/logout -* Method: POST -* Request Header: ```Authorization: Bearer ``` -* JSON Payload: - ``` - { - "refreshToken": "" - } - ``` -* HTTP Response Status Codes: - * 204: No content (successful) - * 400: Bad request (invalid JSON payload) - * 401: Unauthorized (authorization failed due to various reasons) - -### Ping -* Use case: Check if Access Token is still valid. -* URL: /auth/ping -* Method: GET -* Request Header: ```Authorization: Bearer ``` -* HTTP Response Status Codes: - * 204: No content (successful) - * 401: Unauthorized (authorization failed due to various reasons) - -### Confirm -* Use case: User wants to confirm a requests received via email (such as signup, password reset, email change) -* URL: /auth/confirm/`````` -* Method: POST -* HTTP Response Status Codes: - * 204: No content (successful) - * 404: Not found (invalid, expired or already confirmed ID) - -### Set password -* Use case: Logged in user wants to change his password. -* URL: /auth/setpw -* Method: POST -* Request Header: ```Authorization: Bearer ``` -* JSON Payload: - ``` - { - "oldPassword": "", - "newPassword": "" - } - ``` -* HTTP Response Status Codes: - * 204: No content (successful) - * 400: Bad request (invalid JSON payload) - * 401: Unauthorized (authorization failed due to various reasons) - -### Change email address -* Use case: Logged in user wants to change his email address (= username). -* URL: /auth/changeemail -* Method: POST -* Request Header: ```Authorization: Bearer ``` -* JSON Payload: - ``` - { - "password": "", - "email": "" - } - ``` -* HTTP Response Status Codes: - * 204: No content (successful, email sent to new email address - confirmation required before new address gets activated) - * 400: Bad request (invalid JSON payload) - * 401: Unauthorized (authorization failed due to various reasons) - * 409: Conflict (email address already exists) - -### Reset password -* Use case: User forgot his password and wants to reset it. -* URL: /auth/initpwreset -* Method: POST -* JSON Payload: - ``` - { - "email": "" - } - ``` -* HTTP Response Status Codes: - * 204: No content (successful, email sent user - confirmation required before new password is generated) - * 400: Bad request (invalid JSON payload) - -### Delete account -* Use case: User wants to delete his own account. -* URL: /auth/delete -* Method: POST -* Request Header: ```Authorization: Bearer ``` -* JSON Payload: - ``` - { - "password": "" - } - ``` -* HTTP Response Status Codes: - * 204: No content (successful) - * 400: Bad request (invalid JSON payload) - * 401: Unauthorized (authorization failed due to various reasons) - -### TOTP Initialization -* Use case: User wants activate Time-bases One-Time passwords (TOTP) for his account. -* URL: /auth/otp/init -* Method: POST -* Request Header: ```Authorization: Bearer ``` -* HTTP Response Status Codes: - * 200: OK (successful, result in response body payload) - * 400: Bad request (i.e. TOTP already activated) -* HTTP Response Body: - ``` - { - "secret": "", - "image": "", - } - ``` - -### TOTP Confirmation -* Use case: User wants to confirm TOTP activation after scanning the previously generated QR Code with his authenticator app. -* URL: /auth/otp/confirm -* Method: POST -* Request Header: ```Authorization: Bearer ``` -* JSON Payload: - ``` - { - "passcode": "" - } - ``` -* HTTP Response Status Codes: - * 204: No content (successful) - * 400: Bad request (i.e. invalid TOTP) - -### TOTP Deactivation -* Use case: User wants disable TOTP. -* URL: /auth/otp/disable -* Method: POST -* Request Header: ```Authorization: Bearer ``` -* HTTP Response Status Codes: - * 204: No content (successful) - -## Application-/Backend-facing REST API -### Create user -* Use case: Create a new user. -* URL: /users/ -* Method: POST -* JSON Payload: - ``` - { - "email": "", - "password": "", - "confirmed": true|false, - "enabled": true|false, - "data": {} - } - ``` -* HTTP Response Status Codes: - * 201: Created (user successfully created, User ID in response header 'X-Object-ID') - * 400: Bad request (invalid JSON payload) - * 409: Conflict (email address already exists) - -### Get user -* Use case: Get a user object. -* URL: /users/`````` -* Method: GET -* HTTP Response Status Codes: - * 200: OK (successful, result in response body payload) - * 404: Not found (invalid User ID) -* HTTP Response Body: - ``` - { - "email": "", - "password": "", - "confirmed": true|false, - "enabled": true|false, - "data": {} - } - ``` - -### Delete user -* Use case: Delete a user. -* URL: /users/`````` -* Method: DELETE -* HTTP Response Status Codes: - * 204: No content (successful) - * 404: Not found (invalid User ID) - -### Set email address -* Use case: Set a user's email address. -* URL: /users/``````/email -* Method: PUT -* JSON Payload: - ``` - { - "email": "" - } - ``` -* HTTP Response Status Codes: - * 204: No content (successful) - * 400: Bad request (invalid JSON payload) - * 404: Not found (invalid User ID) - * 409: Conflict (email address already exists) - -### Set password -* Use case: Set a user's password. -* URL: /users/``````/password -* Method: PUT -* JSON Payload: - ``` - { - "password": "" - } - ``` -* HTTP Response Status Codes: - * 204: No content (successful) - * 400: Bad request (invalid JSON payload) - * 404: Not found (invalid User ID) - -### Disable user -* Use case: Disable a user account so that the user can't log in anymore. -* URL: /users/``````/disable -* Method: PUT -* HTTP Response Status Codes: - * 204: No content (successful) - * 404: Not found (invalid User ID) - -### Enable user -* Use case: Enable a user account so that the user can log in. -* URL: /users/``````/enable -* Method: PUT -* HTTP Response Status Codes: - * 204: No content (successful) - * 404: Not found (invalid User ID) - -### Set custom user data -* Use case: Store custom JSON data in a user object. -* URL: /users/``````/data -* Method: PUT -* JSON Payload: - ``` - { - - } - ``` -* HTTP Response Status Codes: - * 204: No content (successful) - * 400: Bad request (invalid JSON payload) - * 404: Not found (invalid User ID) - -### Get custom user data -* Use case: Retrieve previously stored custom JSON data from a user object. -* URL: /users/``````/data -* Method: GET -* HTTP Response Status Codes: - * 204: No content (successful) - * 404: Not found (invalid User ID) -* HTTP Response Body: - ``` - { - - } - ``` - -### Check password -* Use case: Checks if a supplied plain-text password matched the user's hashed password. -* URL: /users/``````/checkpw -* Method: POST -* JSON Payload: - ``` - { - "password": "" - } - ``` -* HTTP Response Status Codes: - * 200: OK (successful) - * 400: Bad request (invalid JSON payload) - * 404: Not found (invalid User ID) -* HTTP Response Body: - ``` - { - "result": true|false - } - ``` - -## Configuration Options -Configuration is performed by setting the appropriate environment variables. - -Env | Default | Description ---- | --- | --- -JWT_SIGNING_KEY | 32 Bytes Random String | The private key for signing the JWT access tokens. -PUBLIC_LISTEN_ADDR | 0.0.0.0:8080 | The listening address for the user-facing HTTP server. -PUBLIC_API_PATH | /auth/ | The path for the user-facing REST API. -BACKEND_LISTEN_ADDR | 0.0.0.0:8443 | The listening address for the backend-facing HTTPS server. -BACKEND_CERT_DIR | ./certs/ | The directory containing the backend-facing HTTP server's certificates (mTLS). -BACKEND_GENERATE_CERT | 1 | Whether to create CA and server key-pair on startup (= 1). -BACKEND_CERT_HOSTNAMES | localhost | The hostnames to generate the server certificate for, separated by commas. -BACKEND_CERT_IPS | 127.0.0.1,::1 | The IP addresses to generate the server certificate for, separated by commas. -TEMPLATE_SIGNUP | res/signup.tpl | The email template for signup confirmation mails. -TEMPLATE_CHANGE_EMAIL | res/changeemail.tpl | The email template for email address change confirmation mails. -TEMPLATE_RESET_PASSWORD | res/resetpassword.tpl | The email template for password reset confirmation mails. -TEMPLATE_NEW_PASSWORD | res/newpassword.tpl | The email template for new password mails. -MONGO_DB_URL | mongodb://localhost:27017 | The URL of the MongoDB database server. -MONGO_DB_NAME | jwt_auth_proxy | The database name of the MongoDB database. -CORS_ENABLE | 0 | Whether to enable (= 1) Cross-Origin Resource Sharing (CORS) response headers. -CORS_ORIGIN | * | The value of the 'Access-Control-Allow-Origin' header. -CORS_HEADERS | * | The value of the 'Access-Control-Allow-Headers' header. -SMTP_SERVER | 127.0.0.1:25 | The address and port of the outgoing SMTP server. -SMTP_SENDER_ADDR | no-reply@localhost | The SMTP sender address. -ALLOW_SIGNUP | 1 | Whether to allow (= 1) signup requests at the user-facing HTTP server. -ALLOW_CHANGE_PASSWORD | 1 | Whether to allow (= 1) change password requests at the user-facing HTTP server. -ALLOW_CHANGE_EMAIL | 1 | Whether to allow (= 1) change email address requests at the user-facing HTTP server. -ALLOW_FORGOT_PASSWORD | 1 | Whether to allow (= 1) password reset requests at the user-facing HTTP server. -ALLOW_DELETE_ACCOUNT | 1 | Whether to allow (= 1) "delete my account" requests at the user-facing HTTP server. -TOTP_ENABLE | 0 | Whether to enable (= 1) support for Time-based One-Time Passwords (TOTP) as a second authentication factor (2FA). -TOTP_ISSUER | JWT Auth Proxy | The TOTP Issuer. -TOTP_ENCRYPT_KEY | '' | The passphrase encrypt the TOTP Secrets in the database (minimum length: 16 bytes). Required if TOTP_ENABLE=1. -PROXY_TARGET | http://127.0.0.1:80 | The target server hosting your application backend. -PROXY_WHITELIST | '' | Whitelisted URL prefixes at the target server not requiring a valid authentication. Separate prefixes by colons (':'). Don't use with PROXY_BLACKLIST. -PROXY_BLACKLIST | '' | Blacklisted URL prefixes at the target server requiring a valid authentication. Separate prefixes by colons (':'). Don't use with PROXY_WHITELIST. -ACCESS_TOKEN_LIFETIME | 5 | The access token lifetime in minutes. -REFRESH_TOKEN_LIFETIME | 1,440 | The refresh token lifetime in minutes. -PENDING_ACTION_LIFETIME | 1,440 | The lifetime of pending actions (such as confirmation requests) in minutes. +## Documentation +https://jwt-auth-proxy.readthedocs.io \ No newline at end of file diff --git a/VERSION b/VERSION index 5d4294b..2411653 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.5.1 \ No newline at end of file +0.5.2 \ No newline at end of file diff --git a/docs/app-facing.md b/docs/app-facing.md new file mode 100644 index 0000000..6c45df2 --- /dev/null +++ b/docs/app-facing.md @@ -0,0 +1,192 @@ +# Application-/Backend-facing API +The Application- or Backend-facing REST API is the one that is only accessible by your application's backend. It is not accessible directly from your frontend or the internet. The connection between the REST API Server and your backend which invoked the HTTP REST calls is authenticated and protected using mutual TLS (mTLS). + +## Create user +Create a new user. + +URL: ```/users/``` + +Method: ```POST``` + +JSON Payload: +``` +{ + "email": "", + "password": "", + "confirmed": true|false, + "enabled": true|false, + "data": {} +} +``` + +HTTP Response Status Codes: + +* 201: Created (user successfully created, User ID in response header 'X-Object-ID') +* 400: Bad request (invalid JSON payload) +* 409: Conflict (email address already exists) + +## Get user +Get a user object. + +URL: ```/users/``` + +Method: ```GET``` + +HTTP Response Status Codes: + +* 200: OK (successful, result in response body payload) +* 404: Not found (invalid User ID) + +HTTP Response Body: +``` +{ + "email": "", + "password": "", + "confirmed": true|false, + "enabled": true|false, + "data": {} +} +``` + +## Delete user +Delete a user. + +URL: ```/users/``` + +Method: ```DELETE``` + +HTTP Response Status Codes: + +* 204: No content (successful) +* 404: Not found (invalid User ID) + +## Set email address +Set a user's email address. + +URL: ```/users//email``` + +Method: ```PUT``` + +JSON Payload: +``` +{ + "email": "" +} +``` + +HTTP Response Status Codes: + +* 204: No content (successful) +* 400: Bad request (invalid JSON payload) +* 404: Not found (invalid User ID) +* 409: Conflict (email address already exists) + +## Set password +Set a user's password. + +URL: ```/users//password``` + +Method: ```PUT``` + +JSON Payload: +``` +{ + "password": "" +} +``` + +HTTP Response Status Codes: + +* 204: No content (successful) +* 400: Bad request (invalid JSON payload) +* 404: Not found (invalid User ID) + +## Disable user +Disable a user account so that the user can't log in anymore. + +URL: ```/users//disable``` + +Method: ```PUT``` + +HTTP Response Status Codes: + +* 204: No content (successful) +* 404: Not found (invalid User ID) + +## Enable user +Enable a user account so that the user can log in. + +URL: ```/users//enable``` + +Method: ```PUT``` + +HTTP Response Status Codes: + +* 204: No content (successful) +* 404: Not found (invalid User ID) + +## Set custom user data +Store custom JSON data in a user object. + +URL: ```/users//data``` + +Method: ```PUT``` + +JSON Payload: +``` +{ + +} +``` + +HTTP Response Status Codes: + +* 204: No content (successful) +* 400: Bad request (invalid JSON payload) +* 404: Not found (invalid User ID) + +## Get custom user data +Retrieve previously stored custom JSON data from a user object. + +URL: ```/users//data``` + +Method: ```GET``` + +HTTP Response Status Codes: + +* 204: No content (successful) +* 404: Not found (invalid User ID) + +HTTP Response Body: +``` +{ + +} +``` + +## Check password +Checks if a supplied plain-text password matched the user's hashed password. + +URL: ```/users//checkpw``` + +Method: ```POST``` + +JSON Payload: +``` +{ + "password": "" +} +``` + +HTTP Response Status Codes: + +* 200: OK (successful) +* 400: Bad request (invalid JSON payload) +* 404: Not found (invalid User ID) + +HTTP Response Body: +``` +{ + "result": true|false +} +``` diff --git a/docs/config.md b/docs/config.md new file mode 100644 index 0000000..6772969 --- /dev/null +++ b/docs/config.md @@ -0,0 +1,38 @@ +# Configuration +Configuration is performed by setting the appropriate environment variables. + +Env | Default | Description +--- | --- | --- +JWT_SIGNING_KEY | 32 Bytes Random String | The private key for signing the JWT access tokens. +PUBLIC_LISTEN_ADDR | 0.0.0.0:8080 | The listening address for the user-facing HTTP server. +PUBLIC_API_PATH | /auth/ | The path for the user-facing REST API. +BACKEND_LISTEN_ADDR | 0.0.0.0:8443 | The listening address for the backend-facing HTTPS server. +BACKEND_CERT_DIR | ./certs/ | The directory containing the backend-facing HTTP server's certificates (mTLS). +BACKEND_GENERATE_CERT | 1 | Whether to create CA and server key-pair on startup (= 1). +BACKEND_CERT_HOSTNAMES | localhost | The hostnames to generate the server certificate for, separated by commas. +BACKEND_CERT_IPS | 127.0.0.1,::1 | The IP addresses to generate the server certificate for, separated by commas. +TEMPLATE_SIGNUP | res/signup.tpl | The email template for signup confirmation mails. +TEMPLATE_CHANGE_EMAIL | res/changeemail.tpl | The email template for email address change confirmation mails. +TEMPLATE_RESET_PASSWORD | res/resetpassword.tpl | The email template for password reset confirmation mails. +TEMPLATE_NEW_PASSWORD | res/newpassword.tpl | The email template for new password mails. +MONGO_DB_URL | mongodb://localhost:27017 | The URL of the MongoDB database server. +MONGO_DB_NAME | jwt_auth_proxy | The database name of the MongoDB database. +CORS_ENABLE | 0 | Whether to enable (= 1) Cross-Origin Resource Sharing (CORS) response headers. +CORS_ORIGIN | * | The value of the 'Access-Control-Allow-Origin' header. +CORS_HEADERS | * | The value of the 'Access-Control-Allow-Headers' header. +SMTP_SERVER | 127.0.0.1:25 | The address and port of the outgoing SMTP server. +SMTP_SENDER_ADDR | no-reply@localhost | The SMTP sender address. +ALLOW_SIGNUP | 1 | Whether to allow (= 1) signup requests at the user-facing HTTP server. +ALLOW_CHANGE_PASSWORD | 1 | Whether to allow (= 1) change password requests at the user-facing HTTP server. +ALLOW_CHANGE_EMAIL | 1 | Whether to allow (= 1) change email address requests at the user-facing HTTP server. +ALLOW_FORGOT_PASSWORD | 1 | Whether to allow (= 1) password reset requests at the user-facing HTTP server. +ALLOW_DELETE_ACCOUNT | 1 | Whether to allow (= 1) "delete my account" requests at the user-facing HTTP server. +TOTP_ENABLE | 0 | Whether to enable (= 1) support for Time-based One-Time Passwords (TOTP) as a second authentication factor (2FA). +TOTP_ISSUER | JWT Auth Proxy | The TOTP Issuer. +TOTP_ENCRYPT_KEY | '' | The passphrase encrypt the TOTP Secrets in the database (minimum length: 16 bytes). Required if TOTP_ENABLE=1. +PROXY_TARGET | http://127.0.0.1:80 | The target server hosting your application backend. +PROXY_WHITELIST | '' | Whitelisted URL prefixes at the target server not requiring a valid authentication. Separate prefixes by colons (':'). Don't use with PROXY_BLACKLIST. +PROXY_BLACKLIST | '' | Blacklisted URL prefixes at the target server requiring a valid authentication. Separate prefixes by colons (':'). Don't use with PROXY_WHITELIST. +ACCESS_TOKEN_LIFETIME | 5 | The access token lifetime in minutes. +REFRESH_TOKEN_LIFETIME | 1,440 | The refresh token lifetime in minutes. +PENDING_ACTION_LIFETIME | 1,440 | The lifetime of pending actions (such as confirmation requests) in minutes. \ No newline at end of file diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..b6e164d --- /dev/null +++ b/docs/index.md @@ -0,0 +1,36 @@ +# Welcome to JWT Auth Proxy + +## About JWT Auth Proxy +This JWT Auth Proxy is a lightweight authentication proxy written in Go designed for use in Docker/Kubernetes environments. + +![JWT Auth Proxy](https://raw.githubusercontent.com/virtualzone/jwt-auth-proxy/master/diagram.png) + +JWT Auth Proxy sits between your frontend and your application's backend, handles authentication, and proxies authenticated requests to your backend. It offers REST APIs and logic for signup (incl. double-opt-in), password reset ("forgot my password") and verified email address change. This way, your application's backend can focus on the actual business logic, while relying on secure authentication having been performed before. + +To your application's backend, the JWT Auth Proxy provides an mTLS-secured REST API for modifying user objects and storing custom data per user. + +JWT Auth Proxy uses short-lived JWT access tokens (HMAC-signing with SHA-512) and long-lived UUIDv4 refresh tokens for securely retrieving new access tokens before the old one expires. It supports Two-Factor Authentication (2FA) via Time-based One-Time passwords (TOTP). + +## Features +### User-facing +* Easy-to-use REST API for + * Signup with double-opt-in + * Login (with TOTP optionally) + * Logout + * Password reset (forgot password) + * Email address change with double-opt-in + * JWT access token renewal using long-lived refresh tokens + * Activate and disable Two-Factor Authentication (2FA, TOTP) +* Proxy authenticated requests to your application's backend +* Whitelist backend URLs not requiring authentication (or blacklist) + +### Application-/Backend-facing +* mTLS encrypted connecting (mutual TLS) +* Easy-to-use REST API for + * Create user + * Delete user + * Disable/enable user + * Check password + * Set password + * Set email address + * Store and retrieve custom per-user data (JSON) \ No newline at end of file diff --git a/docs/integration.md b/docs/integration.md new file mode 100644 index 0000000..8a9af56 --- /dev/null +++ b/docs/integration.md @@ -0,0 +1,18 @@ +# Application Integration +JWT Auth Proxy usually integrates with your application like this: + +* Your frontend (i.e. JavaScript based) invokes the User-facing REST API to perform signups, validate logins requests, invoke password resets and more. +* Your application's backend (i.e. REST services) is "hidden" behind the JWT Auth Proxy, receiving only correctly authenticated requests or invokations to URLs on the proxy's whitelist. + +## HTTP Request Headers +When your application's backend receives an HTTP request proxied through the JWT Auth Proxy, it receives all the HTTP request headers sent by the HTTP client/browser, plus: + +* ```Authorization```: The successfully validated JWT access token (format: ```Bearer ```). +* ```X-Auth-UserID```: The user's ID you can use to make calls to the backend-facing REST API. +* ```Forwarded```: Information from the client-facing side of the proxy server. +* ```X-Forwarded-For``` (XFF): The originating IP address of the client. +* ```X-Forwarded-Host``` (XFH): The original host requested by the client in the Host HTTP request header. +* ```X-Forwarded-Proto``` (XFP): The protocol (HTTP or HTTPS) the client used to connect to the proxy. + +## Calling the Backend API +To call the backend-facing API, invoke REST-based HTTP requests from your backend to JWT Auth Proxy's backend-facing REST service. This service is usually listening on port 8443 and requires a valid mTLS certificate. \ No newline at end of file diff --git a/docs/setup.md b/docs/setup.md new file mode 100644 index 0000000..469d78b --- /dev/null +++ b/docs/setup.md @@ -0,0 +1,8 @@ +# Setup +Prerequisites: A MongoDB instance (tested with MongoDB v4). + +Please refer to the [docker-compose.yml](https://github.com/virtualzone/jwt-auth-proxy/blob/master/example/docker-compose.yml) example on how to use the pre-build Docker image. + +The server requires a key and a certificate for providing mTLS encryption for the backend REST API. + +You can generate the server's and clients' keys and certificates manually using OpenSSL. By default, the server will create a CA and generate keys and certificates for both server and client on startup (see BACKEND_GENERATE_CERT environment variable). \ No newline at end of file diff --git a/docs/user-facing.md b/docs/user-facing.md new file mode 100644 index 0000000..0d5151e --- /dev/null +++ b/docs/user-facing.md @@ -0,0 +1,279 @@ +# User-facing API +The User- or Frontend-facing REST API is the one that is directly accessible by your users. The REST API is usually invoked by JavaScript code that ships with your web frontend. + +## Sign up / register new user +Sign up a new user using his unique email address as the username. + +URL: ```/auth/signup``` + +Method: ```POST``` + +JSON Payload: +``` +{ + "email": "", + "password": "" +} +``` + +HTTP Response Status Codes: + +* 201: Created (user successfully signed up, User ID in response header 'X-Object-ID') +* 400: Bad request (invalid JSON payload) +* 409: Conflict (user already exists) + +## Log in +Log in an activated and enabled user, retrieve Access and Refresh Tokens. + +URL: ```/auth/login``` + +Method: ```POST``` + +JSON Payload: +``` +{ + "email": "", + "password": "", + "otp": "" +} +``` +HTTP Response Status Codes: + +* 200: OK (user successfully logged in or additional TOTP required, result in response body payload) +* 400: Bad request (invalid JSON payload) +* 401: Unauthorized (authorization failed due to various reasons) + +HTTP Response Body for successful login: +``` +{ + "accessToken": "", + "refreshToken": "", +} +``` + +HTTP Response Body if TOTP is required: +``` +{ + "otpRequired": true +} +``` + +## Refresh Access Token +Refresh short-lived Access Token with long-lived Refresh Token. + +URL: ```/auth/refresh``` + +Method: ```POST``` + +Request Header: ```Authorization: Bearer ``` + +JSON Payload: +``` +{ + "refreshToken": "" +} +``` + +HTTP Response Status Codes: +* 200: OK (successful, result in response body payload) +* 400: Bad request (invalid JSON payload) +* 401: Unauthorized (authorization failed due to various reasons) + +HTTP Response Body: +``` +{ + "accessToken": "", + "refreshToken": "", +} +``` + +## Log out +Invalidate Refresh Token. + +URL: ```/auth/logout``` + +Method: ```POST``` + +Request Header: ```Authorization: Bearer ``` + +JSON Payload: +``` +{ + "refreshToken": "" +} +``` + +HTTP Response Status Codes: +* 204: No content (successful) +* 400: Bad request (invalid JSON payload) +* 401: Unauthorized (authorization failed due to various reasons) + +## Ping +Check if Access Token is still valid. + +URL: ```/auth/ping``` + +Method: ```GET``` + +Request Header: ```Authorization: Bearer ``` + +HTTP Response Status Codes: + +* 204: No content (successful) +* 401: Unauthorized (authorization failed due to various reasons) + +## Confirm +User wants to confirm a requests received via email (such as signup, password reset, email change) + +URL: ```/auth/confirm/``` + +Method: ```POST``` + +HTTP Response Status Codes: + +* 204: No content (successful) +* 404: Not found (invalid, expired or already confirmed ID) + +## Set password +Logged in user wants to change his password. + +URL: ```/auth/setpw``` + +Method: ```POST``` + +Request Header: ```Authorization: Bearer ``` + +JSON Payload: +``` +{ + "oldPassword": "", + "newPassword": "" +} +``` + +HTTP Response Status Codes: + +* 204: No content (successful) +* 400: Bad request (invalid JSON payload) +* 401: Unauthorized (authorization failed due to various reasons) + +## Change email address +Logged in user wants to change his email address (= username). + +URL: ```/auth/changeemail``` + +Method: ```POST``` + +Request Header: ```Authorization: Bearer ``` + +JSON Payload: +``` +{ + "password": "", + "email": "" +} +``` + +HTTP Response Status Codes: + +* 204: No content (successful, email sent to new email address - confirmation required before new address gets activated) +* 400: Bad request (invalid JSON payload) +* 401: Unauthorized (authorization failed due to various reasons) +* 409: Conflict (email address already exists) + +## Reset password +User forgot his password and wants to reset it. + +URL: ```/auth/initpwreset``` + +Method: ```POST``` + +JSON Payload: +``` +{ + "email": "" +} +``` + +HTTP Response Status Codes: + +* 204: No content (successful, email sent user - confirmation required before new password is generated) +* 400: Bad request (invalid JSON payload) + +## Delete account +User wants to delete his own account. + +URL: ```/auth/delete``` + +Method: ```POST``` + +Request Header: ```Authorization: Bearer ``` + +JSON Payload: +``` +{ + "password": "" +} +``` + +HTTP Response Status Codes: + +* 204: No content (successful) +* 400: Bad request (invalid JSON payload) +* 401: Unauthorized (authorization failed due to various reasons) + +## TOTP Initialization +User wants activate Time-bases One-Time passwords (TOTP) for his account. + +URL: ```/auth/otp/init``` + +Method: ```POST``` + +Request Header: ```Authorization: Bearer ``` + +HTTP Response Status Codes: + +* 200: OK (successful, result in response body payload) +* 400: Bad request (i.e. TOTP already activated) + +HTTP Response Body: +``` +{ + "secret": "", + "image": "", +} +``` + +## TOTP Confirmation +User wants to confirm TOTP activation after scanning the previously generated QR Code with his authenticator app. + +URL: ```/auth/otp/confirm``` + +Method: ```POST``` + +Request Header: ```Authorization: Bearer ``` + +JSON Payload: +``` +{ + "passcode": "" +} +``` + +HTTP Response Status Codes: + +* 204: No content (successful) +* 400: Bad request (i.e. invalid TOTP) + +## TOTP Deactivation +User wants disable TOTP. + +URL: ```/auth/otp/disable``` + +Method: ```POST``` + +Request Header: ```Authorization: Bearer ``` + +HTTP Response Status Codes: + +* 204: No content (successful) \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..da2fc6f --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,10 @@ +site_name: JWT Auth Proxy +theme: readthedocs +nav: + - Home: index.md + - Setup: setup.md + - Configuration: config.md + - Application Integration: integration.md + - User-facing API: user-facing.md + - Backend-facing API: app-facing.md +site_dir: docs_build