Auth0 get meta_data not authenticated - ios

I’m using Auth0 to authenticate my users using my ios app and Iv’e been following the docs on getting the user meta data but it doesn’t work when I try it. Following the docs, this is the method that I’ve written:

AuthenticationViewController

    @IBAction func showLogin(_ sender: UIButton) {
        guard let clientInfo = plistValues(bundle: Bundle.main) else { return }
        Auth0
            .webAuth()
            .scope("openid profile read:current_user")
            .audience("https://" + clientInfo.domain + "/userinfo")
            .start {
                switch $0 {
                case .failure(let error):
                    Loaf("Something went wrong, please try again!", state: .error, location: .bottom, presentingDirection: .vertical, dismissingDirection: .vertical, sender: self).show()
                    print("---WEBAUTH---", error)
                case .success(let credentials):
                    if(!SessionManager.shared.store(credentials: credentials)) {
                        print("Failed to store credentials")
                    } else {
                        SessionManager.shared.retrieveProfile { error in
                            if let error = error {
                                print("---RETRIEVE PROFILE---", error)
                            } else {
                                SessionManager.shared.getMetaData { (error) in
                                    if let error = error {
                                        print("---GETMETADATA---", error)
                                    } else {
                                        DispatchQueue.main.async {
                                            self.performSegue(withIdentifier: "authenticate", sender: self)
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
        }
    }

Session Manager

class SessionManager {
    static let shared = SessionManager()
    private let authentication = Auth0.authentication()
    let credentialsManager: CredentialsManager!
    var profile: UserInfo?
    var credentials: Credentials?
    var patchMode: Bool = false
    
    private init () {
        self.credentialsManager = CredentialsManager(authentication: Auth0.authentication())
        _ = self.authentication.logging(enabled: true)
    }
    
    func retrieveProfile(_ callback: @escaping (Error?) -> ()) {
        guard let accessToken = self.credentials?.accessToken
            else { return callback(CredentialsManagerError.noCredentials) }
        self.authentication
            .userInfo(withAccessToken: accessToken)
            .start { result in
                switch(result) {
                case .success(let profile):
                    self.profile = profile
                    callback(nil)
                case .failure(let error):
                    callback(error)
                }
        }
    }

    func getMetaData(_ callback: @escaping (Error?) -> ()) {
        guard let accessToken = self.credentials?.accessToken
            else { return callback(CredentialsManagerError.noCredentials) }
        Auth0
            .users(token: accessToken)
            .get(profile!.sub, fields: ["user_metadata"], include: true)
            .start { (result) in
                switch result {
                case .success(let user):
                    print(user)
                    callback(nil)
                case .failure(let error):
                    callback(error)
                }
        }
    }

    func store(credentials: Credentials) -> Bool {
        self.credentials = credentials
        // Store credentials in KeyChain
        return self.credentialsManager.store(credentials: credentials)
    }
}
// also contains standard plist func written by Auth0 

this is the error I’m getting:

—GETMETADATA— Failed with unknown error [“error”: Bad Request, “statusCode”: 400, “message”: Bad HTTP authentication header format, “errorCode”: Bearer]

I know that normally you would use Bearer + accessToken to authenticate but I don’t see them use this in the docs or the example project.

1 Like

Hi @MoutPessemier

There seems to be a confusion on “audiences” for the access token. If you are trying to read the user’s metadata using the Management API v2 (https://auth0.com/docs/api/management/v2/get-access-tokens-for-spas), then your audience needs to be: https://{your_auth0_tenant}.auth0.com/api/v2/. This will return a token that will let you make a request to /api/v2/users/{user_id} to read the full user profile.
Having said the above, in general I would stay away of using the Management API v2 to read information about the user from an API. A much simpler and faster way to get user information in an app is to use Custom Claims, where you create a rule that add the information directly in the ID token that the application receives. E.g.:

function (user, context, callback) {
  const namespace = 'https://myapp.example.com/';
  context.idToken[namespace + 'favorite_color'] = user.user_metadata.favorite_color;
  context.idToken[namespace + 'preferred_contact'] = user.user_metadata.preferred_contact;
  callback(null, user, context);
}

Using the above code the app will receive two additional claims with the favorite_color and preferred_contact directly in the authentication response, without needing to use a separate request to the Management API v2 to get that information. And if you use this method you don’t need to set the audience to point to the Management API v2.

1 Like

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.