Memorizzazione e accesso agli attributi
Con IBM Cloud® App ID, puoi compilare le informazioni sui singoli utenti della tua applicazione in un profilo. Le informazioni nel profilo possono essere apprese sui tuoi utenti dal modo in cui interagiscono con la tua applicazione o aggiunte da te per loro conto. Archiviando le informazioni, puoi accedere a esse per facilitare la creazione di esperienze personalizzate della tua applicazione per i tuoi utenti.
Descrizione dei profili
Un profilo utente è costituito da tutte le informazioni conosciute su uno specifico utente, compilate in un oggetto JSON e memorizzate da App ID. Esistono due tipi di informazioni, o attributi, che possono essere ottenuti e archiviati in un
profilo: predefiniti (predefined) e personalizzati (custom). Gli attributi predefiniti sono specifici per l'identità del tuo utente e sono restituiti da un provider di identità quando il tuo utente accede alla tua
applicazione e possono includere delle informazioni come nome o età. Gli attributi personalizzati sono utilizzati per archiviare ulteriori informazioni sui tuoi utenti. Li puoi impostare tu stesso oppure vengono acquisiti quando l'utente interagisce
con la tua applicazione. Gli attributi personalizzati possono includere un ruolo assegnato, una preferenza alimentare o una preferenza di posto lato corridoio su un aeroplano.
Puoi archiviare fino a 100 KB di informazioni per ciascun utente.
Come ottengo le informazioni sul profilo utente?
Esistono diversi modi in cui si possono accedere alle informazioni degli utenti e diverse ragioni per cui si vorrebbe. L'endpoint che scegli di richiamare può variare a seconda del tuo caso d'uso.
Se hai bisogno di lavorare con un'API, controlla la seguente immagine e le informazioni corrispondenti per vedere come vengono estratte le informazioni.
/oauth/v4/<tenantID>/token- Dopo un'autenticazione eseguita correttamente, ricevi token di accesso e identità che contengono le informazioni utente più comuni, ad esempio un nome, un'immagine o una email. Se vuoi aggiungere ulteriori informazioni, puoi utilizzare l' associazione delle attestazioni personalizzate per configurare App ID per inserire informazioni nel token prima che ti venga restituito.
/oauth/v4/<tenantID>/userinfo- Se si vuole vedere una visione approfondita delle informazioni sul profilo dell'utente restituite da un fornitore di identità, si può chiamare l'endpoint
/userinfo. Si consiglia di utilizzare questo endpoint solo se le informazioni non possono essere mappate sul token, poiché richiede ulteriori chiamate di rete. /api/v1/attributes- Se la tua applicazione richiede la lettura e l'aggiornamento degli attributi di profilo personalizzati per un utente attualmente collegato, puoi utilizzare l'endpoint /attributes. Ad esempio, l'utente desidera aggiornare una preferenza alimentare.
/management/v4/<tenantID>/users- Se stai creando interfacce o processi amministrativi che potrebbero applicarsi a più utenti, puoi utilizzare l'API di gestione App ID. In particolare, è possibile utilizzare l'endpoint
/users.
I modi più facili per lavorare con le informazioni utente sono utilizzando la GUI o un SDK. Con queste opzioni, tutte le chiamate API vengono effettuate dietro le quinte per voi.
Accesso agli attributi in fase di esecuzione
Dopo una corretta autenticazione utente, la tua applicazione riceve i token di accesso e identità da App ID. Il servizio inserisce automaticamente un sottoinsieme di attributi nei tuoi token di accesso e identità. Se le informazioni non sono presenti nel token, puoi utilizzare uno qualsiasi dei seguenti endpoint per trovare le informazioni.
Accesso all'endpoint /userinfo
Per visualizzare le informazioni sui tuoi utenti fornite dai tuoi provider di identità configurati, puoi accedere ai tuoi attributi predefiniti.
-
Assicurarti di disporre di un token di accesso valido con un ambito
openid. Puoi verificare che il token è valido utilizzando l'endpoint/introspect. -
Effettuare una richiesta all'endpoint
/userinfo. Se i nuovi token non vengono inoltrati esplicitamente al SDK, App ID utilizza gli ultimi token ricevuti per richiamare e convalidare la risposta. Passare un token di identità è facoltativo, ma superato viene utilizzato per convalidare la risposta.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 } }Output di esempio:
"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" } } ] -
Verificare che l'attestazione
subcorrisponda esattamente all'attestazionesubnel token di identità. Se non corrispondono, non utilizzare le informazioni restituite. Per saperne di più sulla sostituzione dei token, consultare le specifiche OIDC.
Se le modifiche vengono apportate da un provider di identità esterno, puoi ottenere le informazioni aggiornate quando gli utenti accedono nuovamente. I tuoi nuovi token richiamano i dati più aggiornati.
Accesso all'endpoint /attributes
A seconda della tua configurazione, gli attributi sono codificati e salvati come parte di un profilo utente quando un utente interagisce con la tua applicazione. L'interazione può essere un utente che esegue l'accesso o l'impostazione di una preferenza nella tua applicazione. Per accedere agli attributi, passa un token di accesso tramite un metodo 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)
Configurazione degli attributi personalizzati
Puoi aggiungere delle informazioni sui tuoi utenti nel loro profilo, ad esempio un ruolo o una preferenza, configurando un attributo personalizzato. Per impostare gli attributi personalizzati prima che un utente esegua la registrazione alla tua applicazione, vedi Preregistrazione degli utenti futuri.
Per impostazione predefinita, gli attributi personalizzati sono modificabili e possono essere aggiornati utilizzando un token di accesso App ID da un'applicazione client. Senza le dovute precauzioni, l'utente o l'applicazione possono aggiornare gli attributi personalizzati subito dopo il primo accesso dell'utente, se dispongono di un token di accesso. Ciò può potenzialmente portare a conseguenze indesiderate. Ad esempio, un utente potrebbe modificare il suo ruolo da utente ad amministratore e questo potrebbe esporre i privilegi di amministrazione a utenti malintenzionati.
-
Vai alla scheda User profiles > Settings del dashboard App ID.
-
Modifica gli attributi personalizzati in modo che siano impostati su Enabled.
-
Ottenere l'accesso e i token di identità con l'API.
-
Ottieni l'ID tenant, l'ID client, il segreto e l'URL del server OAuth dalle tue credenziali.
-
Codificare il proprio ID client e segreto utilizzando un encoder base64.
-
Utilizzare i seguenti esempi di codice per richiamare i token. Il tipo di concessione utilizzato per ottenere il token può variare a seconda del tipo di autorizzazione con cui si lavora. Per un elenco dettagliato delle opzioni, consultare il sito documentazione 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)
-
-
Utilizzando l'endpoint
attributes, effettua una richiesta 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 }