BF user and app-role context
INFO
Before you start First bind the user under Role Management, then use the roles available in the BFF to drive your feature logic. This page only covers how to read the current logged-in user and current app roles inside a BFF script.
1. How to read them in a script
All BFF standalone endpoint scripts share this function signature:
export default async function(params, context) {
// params: HTTP 请求体
// context: 运行时上下文
}Read the current user and app roles from context:
const FINANCE_APPROVER_ROLE_ID = xxx;
export default async function getCurrentUserRoles(params, context) {
const userInfo = context.userInfo || {};
const appRoles = context.appRoles || [];
// 这里直接用脚本内固定的角色 ID 判断。roleId 对应 app_role_permit.id。
const roleIds = appRoles
.map(role => role.roleId)
.filter(roleId => roleId !== null && roleId !== undefined);
const hasFinanceApproverRole = roleIds.some(
roleId => Number(roleId) === FINANCE_APPROVER_ROLE_ID
);
return {
appCode: context.appCode,
tenantCode: context.tenantCode || null,
userId: userInfo.userId,
username: userInfo.username,
userRole: userInfo.role,
appRoles,
roleIds,
hasFinanceApproverRole
};
}2. Relevant fields in context
| Field | Type | Description |
|---|---|---|
context.userInfo | object | Runtime user context |
context.appRoles | array | App-role relations enabled for the current user under the current appCode |
context.tenantCode | string | Tenant code of the current logged-in user |
context.appCode | string | App code the current BFF execution belongs to |
context.client | object | BFF SDK for data access, SQL, transactions, extensions, and more |
3. Structure of appRoles
context.appRoles is a List<Map<String, Object>>.
Each entry contains:
| Field | Type | Source | Description |
|---|---|---|---|
id | number | user_app_relation.id | Primary key of the user-app relation |
appCode | string | user_app_relation.app_code | App code |
userId | number | user_app_relation.user_id | User ID |
username | string | user_app_relation.username | Username |
status | string | user_app_relation.status | User status in the app; enabled entries have the value ENABLE |
roleType | string | user_app_relation.role_type | Role type, such as ADMIN, DEV, USER, CUSTOM (all custom roles have CUSTOM) |
roleId | number | user_app_relation.role_id | Role configuration ID, referencing app_role_permit.id |
roleName | string | app_role_permit.role_name or the default role description | Role name |
Example response:
[
{
"id": 1001,
"appCode": "demo-app",
"userId": 12345,
"username": "zhangsan",
"status": "ENABLE",
"roleType": "ADMIN",
"roleId": 10,
"roleName": "管理员"
}
]4. Permission model
The permission model is "permissions bind to roles, users bind to roles":
用户
-> user_app_relation
-> roleType / roleId
-> app_role_permit
-> permits
-> PermissionEngine 判断资源动作权限In other words:
user_app_relationrecords which roles a user holds in a given app.app_role_permitrecords which permission configuration a role holds.app_role_permit.permitsstores the role's full permission expression.
If your BFF script only needs to check whether the current user is an admin, developer, regular member, or custom role, context.appRoles is all you need.
5. Common snippets
Check for a specific role ID:
function hasRoleId(context, requiredRoleId) {
const appRoles = context.appRoles || [];
return appRoles.some(role => Number(role.roleId) === Number(requiredRoleId));
}Check for any of several role IDs:
function hasAnyRoleId(context, requiredRoleIds) {
const appRoles = context.appRoles || [];
const requiredIdSet = new Set((requiredRoleIds || []).map(roleId => Number(roleId)));
return appRoles.some(role => requiredIdSet.has(Number(role.roleId)));
}Read basic current-user info:
function getCurrentUser(context) {
const userInfo = context.userInfo || {};
return {
userId: userInfo.userId,
username: userInfo.username,
nickname: userInfo.nickname,
tenantCode: context.tenantCode || userInfo.tenantCode || null
};
}Protect a BFF with a role check:
const FINANCE_APPROVER_ROLE_ID = xxx;
export default async function protectedEndpoint(params, context) {
if (!hasRoleId(context, FINANCE_APPROVER_ROLE_ID)) {
throw new Error("当前用户无指定角色权限");
}
return {
success: true
};
}
function hasRoleId(context, requiredRoleId) {
const appRoles = context.appRoles || [];
return appRoles.some(role => Number(role.roleId) === Number(requiredRoleId));
}6. Notes
context.appRolesincludes only role relations inENABLEstatus under the currentappCode.- A user can hold multiple role relations in the same app, which is why
appRolesis an array. - Use
roleTypeto check system roles;roleNameis better for display or matching custom role names. - Never trust user, role, or permission fields submitted by the frontend. Always rely on
context.userInfoandcontext.appRoles.