- Integrate your backend
- Cloudflare Workers
Integrate your backend
Cloudflare Workers
PropelAuth's Cloudflare Worker library provides all the building blocks you need to add authentication and authorization to your Cloudflare Workers
For the full Library Reference, click here.
Quick example
The following example validates an Authorization HTTP header was sent from a logged-in user.
import {handleError, initAuth} from '@propelauth/cloudflare-worker'
const {validateAuthHeaderAndGetUser} = initAuth({
// The base URL where your authentication pages are hosted.
// You can find your Auth URL under the Backend Integration section for your project at https://app.propelauth.com.
authUrl: "YOUR_AUTH_URL",
// You can manage your api keys under the Backend Integration section for your project.
apiKey: "YOUR_API_KEY",
// This can also be found under the Backend Integration section
verifierKey: `YOUR
MULTILINE
KEY`
});
export default {
async fetch(
request: Request,
env: Env,
ctx: ExecutionContext
): Promise<Response> {
try {
const authHeader = request.headers.get("authorization")
const user = await validateAuthHeaderAndGetUser(authHeader)
return Response.json(user)
} catch (e) {
const error = handleError(e, {logError: true, returnDetailedErrorToUser: true})
return new Response(error.message, {status: error.status})
}
},
};
How it works
For a detailed description of what’s going on under the hood, see here.
Installation
In your Cloudflare workers project, install the @propelauth/cloudflare-worker library.
$ npm install --save @propelauth/cloudflare-worker
Initialize
To initialize the library, call initAuth
.
import {initAuth} from '@propelauth/cloudflare-worker'
const auth = initAuth({
// The base URL where your authentication pages are hosted.
// You can find your Auth URL under the Backend Integration section for your project at https://app.propelauth.com.
authUrl: "YOUR_AUTH_URL",
// You can manage your api keys under the Backend Integration section for your project.
apiKey: "YOUR_API_KEY",
// This can also be found under the Backend Integration section
verifierKey: `YOUR
MULTILINE
KEY`
});
Protect API routes
validateAuthHeaderAndGetUser
This function takes in the Authorization
HTTP header and verifies the request
was made by a valid user. It expects the header to be in the format
Bearer ACCESS_TOKEN
. If the Authorization HTTP header is malformed or doesn’t
contain a valid access token, an
UnauthorizedException
is thrown.
let user;
try {
const authHeader = request.headers.get("authorization")
user = await validateAuthHeaderAndGetUser(authHeader)
} catch (e) {
const error = handleError(e)
return new Response(error.message, {status: error.status})
}
The user object looks like:
Property | Description |
---|---|
userId | The id of the user |
orgIdToOrgMemberInfo | A dictionary of org ids to metadata about the org. Includes all orgs that the user is in |
legacyUserId | The original ID of the user, if the user was migrated from an external source |
The values of orgIdToOrgMemberInfo are OrgMemberInfo’s, with the following fields/functions:
OrgMemberInfo fields/properties | Description |
---|---|
orgId | The id of the org |
orgName | The name of the org |
urlSafeOrgName | A URL-safe version of the name of the org |
assignedRole(): string | The user’s role within the organization. See Roles and Permissions for more details. |
permissions(): string[] | The user’s permissions within the organization. See Roles and Permissions |
isRole(role: string): boolean | Returns True if the user’s role within the organization matches the role passed in |
isAtLeastRole(role: string): boolean | Returns True if the user’s role within the organization is at least the role passed in. If the hierarchy of roles is Owner => Admin => Member, specifying “Admin” will return True for Admins and Owners, but False for Members. |
hasPermission(permission: string): boolean | Return True if the user has a specific permission. The users’ permissions are derived from their role within this organization. |
hasAllPermissions(permissions: string[]): boolean | Return True if the user has all the specified permissions. The users’ permissions are derived from their role within this organization. |
validateAuthHeaderAndGetUserWithOrgInfo
This function will verify that a request was made by a valid user AND that user is in an organization.
Argument | Description |
---|---|
Authorization HTTP Header | It expects the header to be in the format Bearer ACCESS_TOKEN . If the Authorization HTTP header is malformed or doesn’t contain a valid access token, an UnauthorizedException is thrown. |
Required Org Info | An object with optional fields orgId and orgName . This function will make sure the user who made the request is a member of an organization with the specified orgId and orgName . If the user is NOT a member of the specified organization, a ForbiddenException is thrown. |
It returns an object with two fields:
{
user: //...
orgMemberInfo: //...
}
You can see the structure of the user
and orgMemberInfo
objects above.
const { searchParams } = new URL(request.url)
const orgId = searchParams.get('org')
const authHeader = request.headers.get("authorization")
try {
const {user, orgMemberInfo} = await validateAuthHeaderAndGetUserWithOrgInfo(
authHeader, {orgId: orgId}
)
} catch (e) {
const error = handleError(e)
return new Response(error.message, {status: error.status})
}
Roles and Permissions
A user has a Role within an organization. By default, the available roles are Owner, Admin, or Member, but these can be configured. These roles are also hierarchical, so Owner > Admin > Member.
Roles allow you to control what different users can do within your product. If you want to check a user’s role, you can use validateAuthHeaderAndGetUserWithOrgInfoWithExactRole or validateAuthHeaderAndGetUserWithOrgInfoWithMinimumRole.
Permissions are arbitrary strings associated with a role. For example, can_view_billing, ProductA::CanCreate, and ReadOnly are all valid permissions. The PropelAuth dashboard allows you to set up these permissions.
You can use validateAuthHeaderAndGetUserWithOrgInfoWithPermission or validateAuthHeaderAndGetUserWithOrgInfoWithAllPermissions to check for a given permission.
API calls
In addition to protecting API routes, you can make requests to PropelAuth to fetch more information about your users or organizations. You can also create new users, update user metadata, and more.
// Example
const usersResponse = await auth.fetchUsersByQuery({
emailOrUsername: "@example.com",
orderBy: "LAST_ACTIVE_AT_DESC",
});
for (const user of userResponse.users) {
console.log("Found user " + user);
}
See Library Reference for more information on available functionality.
Next Steps
Done with your backend? Next you can deploy to production.