Set user role on register

Hello community I have a noob question. Is there a way to assign the user role on register? I am referring to API users not admin panel users. I don’t know if exists an option similar to after sign up hook, to attach an specific role… thanks.

There is not, we strictly force the default as setting a role on register is considered a security risk. If you take for example an app for a school. During register if a user could select if they are a student or a teacher it could be a security risk to give a student access to teach resources.

Either you will need to add some automation to dynamically change “known” accounts into a teacher role or do it manually after verifying the user.

1 Like

@DMehaffy thanks for your answer, I understand your point, but is not the case. I am building two clients for the Strapi API… and the user can create an account type such father, sponsor, etc. But they can’t select the type from a combobox. Each account type has a specific area, to signup and login, therefore, I need sent the specific role from each area, that’s my case. But I don’t know if I can update the user role after signup.

Thanks and regards…

I would say create additional roles and if the role is based on a specific data point that you can verify automatically then you can use the model lifecycles to modify the user but I would strongly suggest against modifying the code to allow the user to pick their role.

I have custom roles for each area… But I don’t know how to assign it to each user. I will try using lifecycle hooks. I think that can I use beforeCreate() or afterCreate() hook, would be great if can share to me a good example external to documentation use.

It largely depends on the use case to provide an example but for the internal Strapi API:

strapi.query('user', 'users-permissions').update({ id: userIDHere }, { role: roleIDHere })

Can you show me how ca I send an extra param on auth register and use it… I need to catch a role ID to update the new record

post('http://localhost:1337/auth/local/register', {
    username: 'Strapi user',
    email: 'user@strapi.io',
    password: 'strapiPassword',
    role: 'parent' or 'roleID'
  })

./api/user/models/User.js

module.exports = {
	lifecycles: {
    async beforeCreate(data) {
      console.log(data);
    },
    async afterCreate(result, data) {
      console.log(result);
    },
  }
};

This example from documentation not working in the ./api/user/models/User.js path… I have to put that in ./extensions/user-permissions/models/User.js

I am trying with a controller too, But I don’t know how to execute the create function to catch the role on the body request… when new user send data…

@rocfel07 did you manage to solve this problem??im trying to do somthing similar but i cant seem to find a right answer… perhaps making the registration and then updating the role

2 Likes

Maybe it’s too late, but here is the solution:

Go to ./extensions/users-permissions/config/schema.graphql.js
create the file if it doesn’t exist

add this

module.exports = {
    definition: `
          extend input UsersPermissionsRegisterInput {
              role: String!
          }
      `,
    type: {},
    resolver: {},
};

Then, the registration will accept the role string value.

Do you logic to search roles by name, then get the target role id in the beforeCreate and update the new user’s role.

1 Like

@hatim_makki is this only for graphql? i want a rest api sollution pls.

This doesn’t work in strapi 4.0

@Andy_Lai , you are right, it doesn’t work in 4.0. A solution presented here How to add custom GraphQL query to Strapi V4 - The IT Solutions doesn’t work either. It would like like this according to that solution:

export const UsersPermissionsRegisterInput =
  (strapi) =>
  ({ nexus }) => ({
    typeDefs: `

    extend input UsersPermissionsRegisterInput {
      role: String!
    }
  `,
  });

Try this

change this
.node_modules@strapi\plugin-users-permissions\server\controllers\auth.js
*but remember, new update can be rewrite this module and delite this added function, to prevent this, use custom controllers.
**with this approach strapi does not return the role string. But there is no need for it, because of security)))

async register(ctx) {
    // ... (previous code)

    // Validate and extract data from the request
    const params = {
      ..._.pick(ctx.request.body, allowedKeys),
      provider: 'local',
    };

    await validateRegisterBody(params);

    // New code here
    const { role: roleName } = ctx.request.body;

    // Use a new variable name if 'role' is already taken
    let userRole;
    if (roleName && roleName !== 'admin') {
      userRole = await strapi.query('plugin::users-permissions.role').findOne({ where: { name: roleName } });
    }
    if (!userRole) {
      userRole = await strapi.query('plugin::users-permissions.role').findOne({ where: { type: settings.default_role } });
    }

    // Create a new user
    const newUser = {
      ...params,
      role: userRole.id, // Use the new variable 'userRole'
      email: params.email.toLowerCase(),
      username: params.username,
      confirmed: !settings.email_confirmation,
    };

    const user = await getService('user').add(newUser);

    // ... (rest of the function)
}

1 Like

Thank for sharing.