IBM Cloud Docs
Almacenamiento y acceso a los atributos

Almacenamiento y acceso a los atributos

Con IBM Cloud® App ID, puede compilar información sobre los usuarios individuales de la aplicación en un perfil. La información en el perfil se puede obtener de los usuarios por la forma en que interactúan con la app o puede añadirlos usted mismo por ellos. Al almacenar la información, puede acceder a ella para ayudar a crear experiencias personalizadas de la app para los usuarios.

Visión general de los perfiles

Un perfil de usuario es toda la información que se conoce sobre un usuario específico, compilada en un objeto JSON y almacenada por App ID. Hay dos tipos de información, o atributos, que se pueden obtener y almacenar en un perfil: predefined y custom. Los atributos predefinidos son específicos de la identidad del usuario y son los que devuelve un proveedor de identidad cuando el usuario inicia sesión en la app, y puede incluir información como su nombre o su edad. Los atributos personalizados se utilizan para almacenar información adicional sobre los usuarios. Los puede establecer usted o se pueden ir obteniendo sobre el usuario a medida que éste interactúa con la app. Los atributos personalizados pueden incluir un rol asignado, una preferencia de comida o la preferencia por un asiento de pasillo en un avión.

caption-side=bottom"
App ID perfiles de usuario Flujo de información sobre perfiles de usuario

Puede almacenar hasta 100 KB de información de cada usuario.

¿Cómo puedo obtener la información del perfil de usuario?

Existen varias formas diferentes en las que se puede acceder a la información del usuario y varias razones diferentes por las que querría hacerlo. El punto final que elija para llamar puede variar según el caso práctico.

Si necesita trabajar con una API, compruebe la siguiente imagen y la información correspondiente para ver cómo se extrae la información.

caption-side=bottom"
App ID user profile endpoint options Opciones de punto final que pueden utilizarse para acceder a la información del usuario

/oauth/v4/<tenantID>/token
Tras una autenticación satisfactoria, recibe las señales de acceso y de identidad que contienen la información de usuario más común: un nombre, una imagen o un correo electrónico, por ejemplo. Si desea añadir información adicional, puede utilizar correlación de reclamaciones personalizadas para configurar App ID para inyectar la información en la señal antes de que ésta le sea devuelta.
/oauth/v4/<tenantID>/userinfo
Si necesita ver una vista en profundidad de la información de perfil de usuario devuelta por un proveedor de identidad, puede llamar al /userinfo punto final. Se recomienda utilizar este punto final sólo si la información no se puede asignar al token, ya que requiere llamadas de red adicionales.
/api/v1/attributes
Si su aplicación requiere leer y actualizar los atributos de perfil personalizados para un usuario conectado actualmente, puede utilizar el punto final /attributes. Por ejemplo, el usuario desea actualizar una preferencia de comida.
/management/v4/<tenantID>/users
Si está creando interfaces o procesos administrativos que se pueden aplicar a varios usuarios, puede utilizar la API de gestión de App ID. Concretamente, puede utilizar el punto final /users.

Las formas más sencillas de trabajar con la información de usuario son utilizando la GUI o un SDK. Con esas opciones, todas las llamadas de API se realizan en segundo plano para usted.

Acceso a atributos en tiempo de ejecución

Tras una autenticación de usuario satisfactoria, la app recibe señales de acceso e identidad de App ID. El servicio inyecta automáticamente un subconjunto de atributos en las señales de acceso y de identidad. Si la información no está en la señal, puede utilizar cualquiera de los siguientes puntos finales para buscarla.

Acceso al punto final /userinfo

Para ver la información acerca de los usuarios que proporcionan los proveedores de identidades que tiene configurados, puede acceder a sus atributos predefinidos.

  1. Asegúrese de que tiene una señal de acceso válida con un alcance openid. Puede verificar que la señal es válida mediante el punto final /introspect.

  2. Realice una solicitud al punto final /userinfo. Si las nuevas señales no se pasan de forma explícita al SDK, App ID utiliza las últimas señales recibidas para recuperar y validar la respuesta. Pasar una señal de identidad es opcional, pero se utiliza para validar la respuesta.

    GET https://<region>.appid.cloud.ibm.com/oauth/v4/<tenantID>/userinfo
    Authorization: 'Bearer <accessToken>'
    
    // iOS Swift example
    
    AppID.sharedInstance.userProfileManager.getUserInfo(accessToken: String, identityToken: String?) { (error: Error?, userInfo: [String: Any]?) in guard
       let userInfo = userInfo, err == nil {
          return // an error has occurred
       }
       // retrieved user info successfully
    }
    
    AppID appId = AppID.getInstance();
    
    appId.getUserProfileManager().getUserInfo(accessToken, identityToken, new UserProfileResponseListener() {
       @Override
       public void onSuccess(JSONObject userInfo) {
       // retrieved attribute "name" successfully
       }
    
       @Override
       public void onFailure(UserInfoException e) {
       // exception occurred
       }
    });
    
    let userProfileManager = UserProfileManager(options: options)
    
    let accessToken = req.session[WebAppStrategy.AUTH_CONTEXT].accessToken;
    let identityToken = req.session[WebAppStrategy.AUTH_CONTEXT].identityToken;
    
    // Retrieve user info and validate against the given identity token
    userProfileManager.getUserInfo(accessToken, identityToken).then(function (profile) {
       // retrieved user info successfully
    });
    
    // Retrieve user info without validation
    userProfileManager.getUserInfo(accessToken).then(function (profile) {
    // retrieved user info successfully
    });
    
    // Server-side Swift example
    
    let userProfileManager = UserProfileManager(options: options)
    let accessToken = "<accessToken>"
    let identityToken = "<identityToken>"
    
    // If identity token is provided (recommended approach), response is validated against the identity token
    
    userProfileManager.getUserInfo(accessToken: accessToken, identityToken: identityToken) { (err, userInfo) in guard
       let userInfo = userInfo, err == nil {
       return
       }
    }
    
    // Retrieve the UserInfo without any validation
    
    userProfileManager.getUserInfo(accessToken: accessToken) { (err, userInfo) in guard
       let userInfo = userInfo, err == nil {
       return
       }
    }
    

    Salida de ejemplo:

    "sub": "cad9f1d4-e23b-3683-b81b-d1c4c4fd7d4c",
    "name": "John Doe",
    "email": "john.doe@gmail.com",
    "picture": "https://lh3.googleusercontent.com/-XdUIqdbhg/AAAAAAAAI/AAAAAAA/42rbcbv5M/photo.jpg",
    "gender": "male",
    "locale": "en",
    "identities": [
       {
             "provider": "google",
             "id": "104560903311317789798",
             "profile": {
                "id": "104560903311317789798",
                "email": "john.doe@gmail.com",
                "verified_email": true,
                "name": "John Doe",
                "given_name": "John",
                "family_name": "Doe",
                "link": "https://plus.google.com/104560903311317789798",
                "picture": "https://lh3.googleusercontent.com/-XdUIqdbhg/AAAAAAAAI/AAAAAAA/42rbcbv5M/photo.jpg",
                "gender": "male",
                "locale": "en",
                "idpType": "google"
             }
       }
    ]
    
  3. Verifique que la reclamación sub coincida exactamente con la reclamación sub en la señal de identidad. Si no coinciden, no utilice la información devuelta. Para obtener más información sobre la sustitución de tokens, consulte la especificación OIDC.

Si un proveedor de identidad externo hace algún cambio, puede obtener la información actualizada cuando el usuario vuelva a iniciar sesión. Las nuevas señales recuperan los datos más actualizados.

Acceso al punto final /attributes

En función de la configuración, los atributos se cifran y guardan como parte el perfil de usuario cuando este interactúa con la aplicación. La interacción podría ser, por ejemplo, un usuario iniciando sesión o estableciendo una preferencia en la app. Para acceder a los atributos, pase una señal de acceso a través de un método de API.

curl -X GET 'https://<region>.appid.cloud.ibm.com/api/v1/attributes'
-H 'Accept: application/json'
-H 'Authorization: Bearer <accessToken>'
//iOS Swift example

func setAttribute(key: String, value: String, completionHandler: @escaping(Error?, [String:Any]?) -> Void)
func setAttribute(key: String, value: String, accessTokenString: String, completionHandler: @escaping(Error?, [String:Any]?) -> Void)

func getAttribute(key: String, completionHandler: @escaping(Error?, [String:Any]?) -> Void)
func getAttribute(key: String, accessTokenString: String, completionHandler: @escaping(Error?, [String:Any]?) -> Void)

func getAttributes(completionHandler: @escaping(Error?, [String:Any]?) -> Void)
func getAttributes(accessTokenString: String, completionHandler: @escaping(Error?, [String:Any]?) -> Void)

func deleteAttribute(key: String, completionHandler: @escaping(Error?, [String:Any]?) -> Void)
func deleteAttribute(key: String, accessTokenString: String, completionHandler: @escaping(Error?, [String:Any]?) -> Void)
void setAttribute(@NonNull String name, @NonNull String value, UserAttributeResponseListener listener);
void setAttribute(@NonNull String name, @NonNull String value, @NonNull AccessToken accessToken, UserAttributeResponseListener listener);

void getAttribute(@NonNull String name, UserAttributeResponseListener listener);
void getAttribute(@NonNull String name, @NonNull AccessToken accessToken, UserAttributeResponseListener listener);

void deleteAttribute(@NonNull String name, UserAttributeResponseListener listener);
void deleteAttribute(@NonNull String name, @NonNull AccessToken accessToken, UserAttributeResponseListener listener);

void getAllAttributes(@NonNull UserAttributeResponseListener listener);
void getAllAttributes(@NonNull AccessToken accessToken, @NonNull UserAttributeResponseListener listener);
const userProfileManager = require("ibmcloud-appid").UserProfileManager;
userProfileManager.init();
var accessToken = req.session[WebAppStrategy.AUTH_CONTEXT].accessToken;

// get all attributes
userProfileManager.getAllAttributes(accessToken).then(function (attributes) {

        });

// get single attribute
userProfileManager.getAttribute(accessToken, name).then(function (attributes) {

        });

// set attribute value
userProfileManager.setAttribute(accessToken, name, value).then(function (attributes) {

        });

// delete attribute
userProfileManager.deleteAttribute(accessToken, name).then(function () {

        });
//Server-side Swift example

func getAllAttributes(accessToken: String, completionHandler: (Swift.Error?, [String: Any]?) -> Void)
func getAttribute(accessToken: String, attributeName: String, completionHandler: (Swift.Error?, [String: Any]?) -> Void)
func setAttribute(accessToken: String, attributeName: String, attributeValue : "abc", completionHandler: (Swift.Error?, [String: Any]?) -> Void)
func deleteAllAttributes(accessToken: String, completionHandler: (Swift.Error?, [String: Any]?) -> Void)

Establecer atributos personalizados

Puede añadir información sobre los usuarios en el perfil de los mismos, como por ejemplo un rol o una preferencia, estableciendo un atributo personalizado. Para establecer atributos personalizados antes de que un usuario inicie sesión en la aplicación, consulte Registro previo de futuros usuarios.

De forma predeterminada, es posible modificar y actualizar los atributos mediante la señal de acceso de App ID desde una aplicación de cliente. Sin tomar las precauciones adecuadas, el usuario o la aplicación pueden actualizar los atributos personalizados inmediatamente después del primer inicio de sesión del usuario, si tienen una señal de acceso. Hacerlo puede conducir posiblemente a consecuencias no deseadas. Por ejemplo, un usuario podría cambiar el rol de usuario a administrador, lo que podría exponer privilegios administrativos a usuarios malintencionados.

  1. Vaya al separador Perfiles de usuario > Valores del panel de control de App ID.

  2. Cambie los atributos personalizados a Habilitado.

  3. Obtenga tokens de acceso e identidad con la API.

    1. Obtenga el ID de arrendatario, el ID de cliente, el secreto y el URL de servidor OAuth de sus credenciales.

    2. Codifique el ID de cliente y el secreto utilizando un codificador base64.

    3. Utilice los siguientes ejemplos de código para recuperar las señales. El tipo de otorgamiento que utilice para obtener la señal puede diferir según el tipo de autorización con el que trabaje. Para obtener una lista detallada de opciones, consulte la documentación de swagger.

      curl -X POST 'https://<region>.appid.cloud.ibm.com/oauth/v4/<tenantID>/token' \
      -H 'Authorization: Basic base64Encoded{<clientID>:<clientSecret>}' \
      -H 'Accept: application/json' \
      -F 'grant_type=password' \
      -F 'username=testuser@test.com' \
      -F 'password=testuser'
      
      // iOS Swift example
      
      class delegate : TokenResponseDelegate {
         public func onAuthorizationSuccess(accessToken: AccessToken?, identityToken: IdentityToken?, refreshToken: RefreshToken?, response:Response?) {
         //User authenticated
         }
      
         public func onAuthorizationFailure(error: AuthorizationError) {
         //Exception occurred
         }
      }
      
      AppID.sharedInstance.signinWithResourceOwnerPassword(username: username, password: password, delegate: delegate())
      
      AppID.getInstance().signinWithResourceOwnerPassword(getApplicationContext(), username, password, new TokenResponseListener() {
         @Override
         public void onAuthorizationFailure (AuthorizationException exception) {
            //Exception occurred
         }
      
         @Override
         public void onAuthorizationSuccess (AccessToken accessToken, IdentityToken identityToken, RefreshToken refreshToken) {
            //User authenticated
         }
      });
      
      // Declare the API you want to protect
      app.get("/api/protected",
      
         passport.authenticate(APIStrategy.STRATEGY_NAME, {
         session: false
         }),
         function(req, res) {
         // Get full appIdAuthorizationContext from request object
         var appIdAuthContext = req.appIdAuthorizationContext;
      
         appIdAuthContext.accessToken; // Raw access_token
         appIdAuthContext.accessTokenPayload; // Decoded access_token JSON
         appIdAuthContext.identityToken; // Raw identity_token
         appIdAuthContext.identityTokenPayload; // Decoded identity_token JSON
         appIdAuthContext.refreshToken; // Raw refresh_token
         ...
         }
      );
      
      // Server-side swift example
      
      let options = [
         "clientId": "<clientID>",
         "secret": "<secret>",
         "tenantId": "<tenantID>",
         "oauthServerUrl": "<oauthServerURL>",
         "redirectUri": "<appURL>" + CALLBACK_URL
      ]
      let webappKituraCredentialsPlugin = WebAppKituraCredentialsPlugin(options: options)
      let kituraCredentials = Credentials()
      kituraCredentials.register(plugin: webappKituraCredentialsPlugin)
      
  4. Utilizando el punto final attributes, realice una solicitud PUT.

    curl -X PUT "https://<region>.appid.cloud.ibm.com/api/v1/attributes/<attributeName>" \
    -H "Authorization: Bearer <token>" \
    -d "<attributeValue>"
    
    // iOS Swift example
    
    AppID.sharedInstance.userProfileManager?.setAttribute("key", "value") { (error, result) in
       guard let result = result, error == nil else {
          return // an error has occurred
       }
    // attributes recieved as a Dictionary
    })
    
    appId.getUserProfileManager().setAttribute(name, value, useThisToken, new UserProfileResponseListener() {
       @Override
       public void onSuccess(JSONObject attributes) {
       // attributes received in JSON format on successful response
       }
    
       @Override
       public void onFailure(UserAttributesException e) {
       // exception occurred
       }
    });
    
    const userProfileManager = require("ibmcloud-appid").UserProfileManager;
    userProfileManager.init();
    
    var accessToken = req.session[WebAppStrategy.AUTH_CONTEXT].accessToken;
    
    userProfileManager.setAttribute(accessToken, name, value).then(function (attributes) {
       // attributes returned as dictionary
    });
    
    // Server-side Swift
    
    let userProfileManager = UserProfileManager(options: options)
    let accesstoken = "access token"
    
    userProfileManager.setAttribute(accessToken: accessToken, attributeName: "name", attributeValue : "abc") { (error, response) in
       guard let response = response, error == error else {
       return // an error has occurred
       }
       // attributes received as a Dictionary
    }