auth-proxy is a simple one-command proxy that authenticates your HTTP requests and redirects to a pre-built sign-in page if a user is not authenticated.
First, sign in and create your API keys on Stack Auth cloud (or you can host it locally). Stack Auth is the open-source Auth0 alternative.
Then, start your application server on port 3000
and run the proxy with the following command:
docker run \
-e NEXT_PUBLIC_STACK_PROJECT_ID=<project-id> \
-e NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=<client-key> \
-e STACK_SECRET_SERVER_KEY=<server-key> \
-e SERVER_PORT=3000 \
-e PROXY_PORT=3001 \
-p 3001:3001 \
stackauth/auth-proxy:latest <patterns>
You can now access your application server at localhost:3001 and all the routes under the protected patterns will only be accessible by authenticated users.
The protected patterns are URL patterns (check out the syntax here). Don't forget to include the leading /
and handling the trailing /
. For example, if you want to protect everything under /a
and only the route /b
(not /b/c
), you can run
... stackauth/auth-proxy:latest "/a(/*)" "/b(/)"
.
If you don't have an application server, you can run our example server to play around with the proxy
Start the example server on port 3000:
git clone git@github.com:stack-auth/auth-proxy.git
cd express-example-server
npm install
npm run dev
You can check out the original server without the proxy at localhost:3000.
Now, open a new terminal and run the proxy server on port 3000:
docker run \
-e NEXT_PUBLIC_STACK_PROJECT_ID=<project-id> \
-e NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=<client-key> \
-e STACK_SECRET_SERVER_KEY=<server-key> \
-e SERVER_PORT=3000 \
-e PROXY_PORT=3001 \
-p 3001:3001 \
stackauth/auth-proxy:latest "/protected(/*)"
You can explore the proxy at localhost:3001.
If you access a protected page through the proxy without being authenticated, you will be redirected to a sign-in page like this (customizable on the dashboard):
After signing in, you will be able to access the protected pages.
To retrieve user information from your webpage, you can read the headers as shown in this JavaScript Express + handlebars example (works similarly on other languages/frameworks):
const express = require("express");
const handlebars = require("handlebars");
const app = express();
const template = handlebars.compile(`
<div>
{{#if authenticated}}
<p>Name: {{displayName}}</p>
<p><a href="/handler/account-settings">Account Settings</a></p>
{{else}}
<p><a href="/handler/sign-in">Sign In</a></p>
{{/if}}
</div>
`);
app.get('/', (req, res) => {
const authenticated = !!req.headers['x-stack-authenticated'];
const displayName = req.headers['x-stack-user-display-name'] || '';
const html = template({ authenticated, displayName });
res.send(html);
});
app.listen(3000);
Available headers:
x-stack-authenticated
: "true" if authenticated; not present otherwise.x-stack-user-id
x-stack-user-primary-email
x-stack-user-display-name
Available URLs (redirect your app server to these URLs as needed):
/handler/sign-in
/handler/sign-up
/handler/sign-out
: Clears cookies and redirects back to your homepage./handler/account-settings
: Users can update their email, display name, password, etc./handler/me
: If you make a request to this URL with the user's session cookie, you will get the client information in JSON. This is useful for client-side apps.
When a request is received, the logic is as follows:
if url is /handler/*:
render the auth pages
else:
if user is not authenticated && url is protected:
redirect to /handler/sign-in
else:
forward the request to your server with user info headers
graph TB
Client((Request))
Proxy[Auth Proxy]
YourServer[Your Server]
StackAuthServer[Stack Auth Server]
Client --> Proxy
Proxy --> |"add user info headers"| YourServer
Proxy --> StackAuthServer
StackAuthServer --> Proxy
classDef container fill:#1168bd,stroke:#0b4884,color:#ffffff
class StackAuthServer container
class YourServer container
class Proxy container