속성 저장 및 액세스
IBM Cloud® App ID를 사용하면 애플리케이션의 개별 사용자에 관한 정보를 프로파일로 컴파일할 수 있습니다. 프로파일에 있는 정보는 귀하가 앱과 상호작용하는 방식을 통해 사용자에 관해 배우게 되거나 귀하가 사용자 대신 추가할 수 있습니다. 정보를 저장하면 사용자를 위해 앱의 개인화된 환경을 만드는 데 도움이 되도록 이 정보에 액세스할 수 있습니다.
프로파일 이해
사용자 프로파일은 특정 사용자에 대해 알려진 모든 정보로 하나의 JSON 오브젝트로 컴파일되고 App ID에 의해 저장됩니다. 획득하여 프로파일에 저장할 수 있는 정보 또는 속성의 유형은 predefined와 custom의 두 가지가 있습니다. 사전 정의된 속성은 사용자 ID로 국한되며, 사용자가 앱에 사인인할 때 ID 제공자에서 리턴하고, 사용자 이름 및 연령 등의 정보를 포함할
수 있습니다. 사용자 정의 속성은 사용자에 대한 추가 정보를 저장하는 데 사용됩니다. 이 속성은 본인이 직접 설정하거나 사용자가 앱과 상호작용할 때 해당 사용자에 대해 학습될 수 있습니다. 사용자 정의 속성에는 지정된 역할, 음식 선호도 또는 비행기에서 선호하는 통로 좌석 등이 포함될 수 있습니다.
각각의 사용자에 대해 최대 100KB의 정보를 저장할 수 있습니다.
사용자 프로파일 정보를 얻으려면 어떻게 해야 합니까?
사용자 정보에 액세스할 수 있는 여러 가지 방법과 함께 해당 정보에 액세스하려는 몇 가지 다른 이유가 있습니다. 호출하기 위해 선택하는 엔드포인트는 유스 케이스에 따라 다를 수 있습니다.
API를 사용하여 작업해야 하는 경우 다음 이미지와 해당 정보를 참조하여 정보를 가져오는 방법을 확인하십시오.
/oauth/v4/<tenantID>/token- 인증에 성공하고 나면 가장 일반적인 사용자 정보(이름, 사진 또는 이메일)를 포함하는 액세스 및 ID 토큰을 받습니다. 정보를 추가하려면 사용자 정의 청구-맵핑을 사용하여 사용자에게 리턴하기 전에 정보를 토큰에 삽입하도록 App ID를 구성할 수 있습니다.
/oauth/v4/<tenantID>/userinfo- ID 제공자가 리턴하는 사용자 프로파일 정보를 자세히 보려면
/userinfo엔드포인트를 호출할 수 있습니다. 이 엔드포인트는 추가 네트워크 호출이 필요하므로 정보를 토큰에 매핑할 수 없는 경우에만 사용하는 것이 좋습니다. /api/v1/attributes- 애플리케이션에서 현재 로그인된 사용자의 사용자 정의 프로파일 속성을 읽고 업데이트해야 하는 경우, /attributes 엔드포인트를 사용할 수 있습니다. 예를 들어, 사용자가 음식 선호도를 업데이트하려고 합니다.
/management/v4/<tenantID>/users- 여러 사용자에게 적용할 수 있는 관리 인터페이스 또는 프로세스를 빌드하는 경우 App ID 관리 API를 사용할 수 있습니다. 특히
/users엔드포인트를 사용할 수 있습니다.
사용자 정보를 사용하는 가장 쉬운 방법은 GUI 또는 SDK를 사용하는 것입니다. 해당 옵션을 사용하면 모든 API 호출이 백그라운드에서 수행됩니다.
런타임 시 속성에 액세스
사용자 인증이 정상적으로 완료되면 앱은 App ID로부터 액세스 및 ID 토큰을 받습니다. 서비스에서 속성의 서브세트를 사용자의 액세스 및 ID 토큰에 자동으로 삽입합니다. 정보가 토큰에 없으면 다음 엔드포인트를 사용하여 정보를 찾을 수 있습니다.
/userinfo 엔드포인트 액세스
구성된 ID 제공자가 제공하는 사용자 정보를 확인하기 위해 사전 정의된 속성에 액세스할 수 있습니다.
-
openid범위를 사용하여 올바른 액세스 토큰이 있는지 확인하십시오./introspect엔드포인트를 사용하여 토큰이 올바른지 확인할 수 있습니다. -
/userinfo엔드포인트에 요청합니다. 새 토큰이 SDK에 명시적으로 전달되지 않으면 App ID에서 마지막으로 수신된 토큰을 사용하여 응답을 검색하고 유효성을 검증합니다. 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청구가 ID 토큰의sub청구와 정확히 일치하는지 확인하십시오. 일치하지 않는 경우 리턴된 정보를 사용하지 마십시오. 토큰 대체에 대해 자세히 알아보려면 OIDC 사양을 참조하세요.
외부 ID 제공자가 변경사항을 작성한 경우 사용자가 다시 로그인할 때 업데이트된 정보를 가져올 수 있습니다. 새 토큰이 최신 데이터를 검색합니다.
/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 및 시크릿을 인코딩하십시오.
-
토큰을 검색하려면 코드를 사용하십시오. 토큰을 얻을 때 사용하는 권한 부여 유형은 작업 중인 권한 유형에 따라 달라질 수 있습니다. 자세한 옵션 목록은 스웨거 문서를 참조하세요.
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 }