I have made application which requires login and signup. The data fields of users are like (name, emailid, password and role_type(default is visitor). So there are two roles- Admin and visitor. I have a page called UserManagement, where I can change the type of user from admin to visitor or vice versa. I did this previously by storing the user data in a Database and modifying the role of that user via a typical API request. Now, recently, I shifted to AWS Cognito for storing and managing all users. I had a name, email and password as usual, and for role I had to make a custom attribute called role (custom:role like this), and then I could have all the same parameters as previously. Now I want to know how I can display all users and also change their custom:role type attribute from visitor to admin and vice versa using Cognito from UI. Do I need to implement an API for handling this or do you guys have any other ideas on this?
I think, by default, Cognito doesn’t allow changing attributes of other users.
Any Ideas or Suggestions are Appreciated.
This is how my signup looks like for reference
import React, { useState } from 'react';
import { toast, Toaster } from 'react-hot-toast';
import { useNavigate, Link } from 'react-router-dom';
import UserPool from './UserPool';
const Signup = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [confirmPassword, setConfirmPassword] = useState('');
const [name, setName] = useState('');
const navigate = useNavigate();
const handleSignup = async (e) => {
e.preventDefault();
if (password !== confirmPassword) {
toast.error('Passwords do not match');
return;
}
try {
await new Promise((resolve, reject) => {
UserPool.signUp(
email,
password,
[
{ Name: 'name', Value: name },
{ Name: 'email', Value: email },
{ Name: 'custom:role', Value: 'admin' }
],
null,
(err, data) => {
if (err) reject(err);
else resolve(data);
}
);
});
toast.success('Signup successful. Please check your email for the confirmation code.', {
duration: 3000,
onClose: () => navigate('/confirm-email'),
});
} catch (err) {
console.error(err);
toast.error(err.message || 'An error occurred. Please try again.');
}
};
And this is how my UserPool looks like:
import { CognitoUserPool } from "amazon-cognito-identity-js";
import { cognito_user_pool_id , cognito_client_id } from "../utils/config";
const poolData = {
UserPoolId: cognito_user_pool_id,
ClientId: cognito_client_id,
};
export default new CognitoUserPool(poolData);
Apporch 1: using frontEnd
user attributes are updated directly from the frontend using AWS Amplify's Auth module
, which retrieves the current authenticated user and updates their attributes asynchronously. This approach is straightforward and allows real-time updates but requires proper handling of authentication and error management on the client side.
async function updateUserAttribute(attributeKey: string, value: string) {
try {
// Get the current authenticated user
const currentUser = await Auth.getCurrentUser();
// Update the user attribute
const result = await Auth.updateUserAttributes(currentUser, {
[attributeKey]: value,
});
// Check if the update was successful
console.log(`Successfully updated ${attributeKey} to ${value}.`);
} catch (error) {
console.error("Error updating user attribute:", error);
}
}
updateUserAttribute("custom:myCustomAttribute", "New Value");
Apporch 2: using CKD python (much easier)
leverages AWS Lambda and Python’s Boto3 SDK to update user attributes programmatically. The Lambda function receives a request body, extracts the user’s email and attributes, and calls admin_update_user_attributes. This server-side approach simplifies attribute updates by managing them in one place, but it requires IAM permissions to ensure secure access to the Cognito User Pool
def update_user(body):
data = json.loads(body)
email = data.get("email")
attributes_to_update = data.get("attributes", {})
user_attributes = []
for key, value in attributes_to_update.items():
user_attributes.append({"Name": key, "Value": value})
try:
cognito_client.admin_update_user_attributes(
UserPoolId=user_pool_id, Username=email, UserAttributes=user_attributes
)
return {"statusCode": 200, "body": json.dumps("User updated successfully")}
except Exception as e:
return {"statusCode": 500, "body": json.dumps(str(e))}
Note:
- To execute the
admin_update_user_attributes
function, the Lambda
function must have permission to perform this action on the specified
Cognito User Pool. This requires the following IAM policy
permissions: