Authorization checks
It's best practice to always verify whether or not a user is authorized to access sensitive information, important content, or exclusive features. Authorization is the process of determining the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions.
Clerk provides two main features that can be used to implement authorization checks:
- Organizations
- Users can be assigned Roles and Permissions
- Useful for Role-based and Permission-based access control
- Billing
- Users can subscribe to Plans and Features
- Useful for Subscription-based and Feature-based access control
In your Android application, use Clerk.has() to check whether the signed-in user is authorized. It returns false when no user is signed in, and when the session isn't active, for example while the user still has session tasks to complete.
Important considerations
- When doing authorization checks, it's recommended to use Permission-based over Role-based, and Feature-based over Plan-based authorization, as these approaches are more granular, flexible, and more secure.
- Checking for a Role or Permission depends on the user having an . Without an Active Organization, Role and Permission checks return
false. has()runs on the device and only controls what your app shows. Always check authorization again on your backend before returning protected data or performing a protected action. See the Backendhas()helper.
Check Roles and Permissions
if (Clerk.has(permission = "org:invoices:create")) {
// Create the invoice.
}
if (Clerk.has(role = "org:admin")) {
// Show admin actions.
}Clerk.has() reads the session at the moment you call it. In a composable, collect Clerk.sessionFlow and call checkAuthorization() on the session so the UI updates when the session changes. checkAuthorization() doesn't check the session's status, so only call it on an active session to match Clerk.has().
@Composable
fun InvoiceActions() {
val session by Clerk.sessionFlow.collectAsState()
val activeSession = session?.takeIf { it.status == Session.SessionStatus.ACTIVE }
if (activeSession?.checkAuthorization(permission = "org:invoices:create") == true) {
Button(onClick = { /* Create the invoice. */ }) {
Text("Create invoice")
}
}
}Check Plans and Features
A Plan or Feature slug without a prefix matches either the user's or the Subscription. Prefix it with user: or org: to check only one of them.
if (Clerk.has(feature = "widgets")) {
// Show the widgets Feature.
}
if (Clerk.has(plan = "org:gold")) {
// Show content for Organizations on the Gold Plan.
}Plan and Feature checks read the current session token, so a Subscription change is reflected after the session token refreshes. To read Subscription details, use the Billing APIs.
Require recent reverification
Pass a reverification requirement to check whether the user has reverified recently. You can check it on its own, or together with other conditions. When you pass more than one condition, has() returns true only if all of them pass.
if (Clerk.has(reverification = ReverificationConfig.Strict)) {
// The user reverified in the last 10 minutes.
}
if (Clerk.has(permission = "org:invoices:delete", reverification = ReverificationConfig.Moderate)) {
// Show the Delete invoice button.
}
val recentlyVerified =
Clerk.has(
reverification = ReverificationConfig.Custom(
level = SessionVerification.Level.FIRST_FACTOR,
afterMinutes = 30,
),
)The reverification presets are:
For a user who hasn't set up a second factor, the second-factor and multi-factor presets accept a recent first factor instead.
Check a specific session
Clerk.has() checks the current session, and only when it's active. To check another session, for example in an app that supports multiple sessions, call checkAuthorization() on that Session with the same arguments.
Feedback
Last updated on