Search code examples
iosswiftxcodegoogle-oauthgoogle-books

Google Books Oauth access token authorization error


Hi i have been developing an app that would let the user search for the books using the Google Books API. Everything was working fine until i wanted to access user's favorite books, add and delete them. The error is about authorization. The google books api says here to access the favorite books as

GET https://www.googleapis.com/books/v1/mylibrary/bookshelves?key=yourAPIKey Authorization: /* auth token here */

What i am doing is this.

var userId: String?
    if(UserStats.currentUser?.authentication.idToken != nil){
        userId = UserStats.currentUser?.authentication.idToken
    }
    guard let id = userId else{
        print("User Not authenticated")
        return
    }
    print("USer ID : \(id)")
    let theUrl = URL(string: "https://www.googleapis.com/books/v1/mylibrary/bookshelves?key=AIzaSyBIDJ50ak-caS3M-6nSVbxdN_SmssAlTRI)")
    if let url = theUrl{
        print("Search Called")
        var urlRequest = URLRequest(url: url)
        urlRequest.httpMethod = "GET"
        urlRequest.setValue(id, forHTTPHeaderField: "Authorization")
        print("URL : " + url.absoluteString)
        let task = URLSession.shared.dataTask(with: urlRequest, completionHandler: {
            (data, response, error) in

            if response != nil{
                if let res = response as? HTTPURLResponse{
                    if(res.statusCode == 408)
                    {
                        MessageBox.Show(message: "Error : Request TimeOut", title: "Error", view: self)
                    }

                }
            }

            if error != nil{
                print("Error \(error?.localizedDescription)")
                MessageBox.Show(message: (error?.localizedDescription)!, title: "An error occurred", view: self)

            }
            else{
                do{

                    let jsonData  = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
                    print(jsonData)
                }catch{
                }
            }
        }
    }
}

Every time i run the code it gives me error. The error is here

{
error =     {
    code = 401;
    errors =         (
                    {
            domain = global;
            location = Authorization;
            locationType = header;
            message = "Invalid Credentials";
            reason = authError;
        }
    );
    message = "Invalid Credentials";
};
}

I am using Google Sign in sdk for iOS and here is how i am trying to authenticate and it successfully done.

GIDSignIn.sharedInstance().delegate = self
    GIDSignIn.sharedInstance().uiDelegate = self
    GIDSignIn.sharedInstance().clientID = "1049478111900-4q2m623kj5m0fev7fbqq93tk7rgjvs2f.apps.googleusercontent.com"
    GIDSignIn.sharedInstance().scopes.append("https://www.googleapis.com/auth/books")
GIDSignIn.sharedInstance().signIn()

The sign in is successfull as i do see a Success printed when signed in successfully and also i am able to retrieve accessToken and idToken of the signed in user. here is the idToken i got printed.

ID Token for Signed In user

eyJhbGciOiJSUzI1NiIsImtpZCI6ImNiMDE1MDIxOWM5Y2NlZTBjY2Y3MDg2OTA4NmIxYjVmNGIzMGVmNWIifQ.eyJhenAiOiIxMDQ5NDc4MTExOTAwLTRxMm02MjNrajVtMGZldjdmYnFxOTN0azdyZ2p2czJmLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiYXVkIjoiMTA0OTQ3ODExMTkwMC00cTJtNjIza2o1bTBmZXY3ZmJxcTkzdGs3cmdqdnMyZi5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsInN1YiI6IjEwOTI5NDQ5ODE2OTA4NjY1OTU5NyIsImVtYWlsIjoic2FsbWFubWFqaWQxNEBnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXRfaGFzaCI6IlNMRzRoTGlrQXExZmQ2MnlnWklKR2ciLCJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJpYXQiOjE0OTMxMTE4NjAsImV4cCI6MTQ5MzExNTQ2MH0.Ct1aGjA6K8Vev_FmdjCj5hGJKyALY9jUcakbp4HSesarK8LHjEe2wZ1-8FR-FEyufIDTPENEkYpSXQRGYuHKXYmykNq6LMcRSWmR2JV8P5hDxwYPKcMwG4EgcvrEHncVBzjinn652mVHap6uBzwC4nvbpprpGKuglxZrqBKSobBthZnDitgyuMseWUq0lrfunNyA89g3KD9twjMMIDTMnP40u6if10T7P6JyedSoDgoOZ6rmhQOckovA1ery1rPl0zwvoRrbZ2GS_z-Zzz8ujhfyuxex-0yYExhVF09Gl4lvf5zySnSSbIGi6MIYaZC3W0-WaU4t0Hgho1kujl3ryw

Please do help me with this issue. I have been working this all night and couldn't sort this out. Please let me know if there is any better approach or i can solve this.


Solution

  • Option 1:

    URL(string: "https://www.googleapis.com/books/v1/mylibrary/bookshelves?access_token=YourToken)")
    

    Note: Key is used for public access access token is for private you only need one or the other

    Note 2: you can test this by placing

    https://www.googleapis.com/books/v1/mylibrary/bookshelves?access_token=YourToken
    

    in any web browser.

    Option 2:

    Header should look like this

    Authorization, Bearer accessToken

    I think you are missing bearer.

    You do not need to do both of these one or the other is fine.

    When sending the access token in the "Authorization" request header field defined by HTTP/1.1 [RFC2617], the client uses the "Bearer" authentication scheme to transmit the access token.

    Authorization : Bearer AccessToken