儲存和存取屬性
使用 IBM Cloud® App ID,您可以將個別應用程式使用者的相關資訊編譯成設定檔。 透過使用者與您應用程式互動,或者您代表使用者進行新增,設定檔中會有使用者的相關資訊。 儲存此資訊,即可對其進行存取,以協助建立使用者的個人化應用程式體驗。
瞭解設定檔
使用者設定檔是關於特定使用者的所有已知資訊 - 編譯成一個 JSON 物件,並由 App ID 儲存。 在設定檔中可以取得和儲存兩種類型的資訊(或屬性):predefined和custom。 預先定義的屬性是使用者身分所特有,當使用者登入應用程式時會由身分提供者傳回,且可以包含例如姓名或年齡的資訊。 自訂屬性用來儲存使用者的其他相關資訊。 它們可以由您設定,或是在使用者與應用程式互動時瞭解。 自訂屬性可能包含已指派的角色、食物喜好或飛機上喜好的走道座位。
您最多可以為每位使用者儲存 100 KB 的資訊。
如何取得使用者設定檔資訊?
您可以使用數種不同的方式來存取使用者資訊,以及數個您想要存取的不同原因。 根據使用案例,選擇呼叫的端點可能會有所不同。
如果您需要使用 API,請參閱下圖和對應的資訊,以瞭解如何取回資訊。
/oauth/v4/<tenantID>/token- 成功鑑別後,您將收到存取記號和身分記號,其中包含最常見的使用者資訊,例如姓名、照片或電子郵件。 如果您要新增其他資訊,可以使用自訂宣告對映來配置 App ID,使其將相關資訊注入記號,然後將記號傳回給您。
/oauth/v4/<tenantID>/userinfo- 如果您需要深入檢視由身分提供者傳回的使用者個人資料資訊,您可以呼叫
/userinfo端點。 建議僅在資訊無法映射至標記的情況下使用此端點,因為它需要額外的網路呼叫。 /api/v1/attributes- 如果應用程式需要讀取和更新現行已登入使用者的自訂設定檔屬性,則可以使用 /attributes 端點。 例如,使用者想要更新食品喜好設定。
/management/v4/<tenantID>/users- 如果您要建置可能適用於多個使用者的管理介面或處理程序,則可以使用 App ID 管理 API。 具體而言,您可以使用
/users端點。
使用使用者資訊的最簡單方法是利用 GUI 或 SDK。 有了這些選項,所有的 API 呼叫都會在幕後為您完成。
在執行時期存取屬性
在成功進行使用者鑑別之後,您的應用程式會從 App ID 收到存取及身分記號。 該服務會自動將部分屬性注入您的存取記號和身分記號中。 如果記號中沒有這些資訊,則可以使用下列任一端點來尋找這些資訊。
存取 /userinfo 端點
若要查看已配置之身分提供者所提供的使用者相關資訊,您可以存取預先定義的屬性。
-
確保您具有含
openid範圍的有效存取記號。 您可以使用/introspect端點來驗證記號是否有效。 -
向
/userinfo端點提出請求。 如果新的記號未明確地傳遞至 SDK,則 App ID 會使用最後一個收到的記號來擷取及驗證回應。 傳遞身分記號是選用的,但傳遞是用來驗證回應。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 } }輸出範例:
"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" } } ] -
驗證
sub宣告與身分記號中的sub宣告完全相符。 如果這些不相符,則請不要使用傳回的資訊。 若要瞭解更多關於代號取代的資訊,請參閱 OIDC 規格。
如果外部身分提供者進行變更,則您可以在使用者重新登入時取得更新過的資訊。 您的新記號會擷取最新的資料。
存取 /attributes 端點
取決於您的配置,當使用者與您的應用程式互動時,屬性會加密並儲存為使用者設定檔的一部分。 互動可能是使用者登入,或在您的應用程式中設定喜好設定。 若要存取屬性,請透過 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)
設定自訂屬性
您可以透過設定自訂屬性,將使用者的相關資訊(例如角色或喜好)新增至其設定檔。 若要在使用者登入應用程式之前設定自訂屬性,請參閱預先登錄未來使用者。
依預設,自訂屬性是可修改的,而且可以使用來自用戶端應用程式的 App ID 存取記號予以更新。 如果沒有採取適當的預防措施,使用者或應用程式都可以在第一次使用者登入後,立即更新自訂屬性 (如果他們有存取權標)。 這樣做有可能導致意想不到的後果。 例如,使用者可將其角色從使用者變更為管理,而這可能會向惡意使用者公開管理專用權。
-
移至 App ID 儀表板的使用者設定檔 > 設定標籤。
-
將自訂屬性切換至已啟用。
-
使用 API 取得存取及身分記號。
-
從您的認證取得您的承租戶 ID、用戶端 ID、密碼和 OAuth 伺服器 URL。
-
使用 base64 編碼器來編碼用戶端 ID 和密碼。
-
請使用下列程式碼範例來擷取記號。 您用來取得標記的授予類型可能會因您使用的授權類型而異。 如需詳細的選項清單,請參閱 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)
-
-
使用
attributes端點,提出 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 }