 
         // extract the code from the URL
         let queryParamsDict = self.parametersFrom(queryString: url?.query)
-        let code = queryParamsDict["code"]
+
         // if exists perform the exchange
-        if (code != nil) {
-            self.exchangeAuthorizationCodeForAccessToken(code: code!, completionHandler: completionHandler)
-            // update state
-            state = .authorizationStateApproved
+        if let code = queryParamsDict["code"] {
+            if queryParamsDict["state"] == requestIdentifier {
+                self.exchangeAuthorizationCodeForAccessToken(code: code, completionHandler: completionHandler)
+                // update state
+                state = .authorizationStateApproved
+            } else {
+                let error = NSError(domain: AGAuthzErrorDomain, code: AGErrorCodes.wrongStateParameter, userInfo: [:])
+                completionHandler(nil, error)
+            }
         } else {
             guard let errorName = queryParamsDict["error"] else {
                 let error = NSError(domain:AGAuthzErrorDomain, code: AGErrorCodes.general, userInfo:["NSLocalizedDescriptionKey": "User cancelled authorization."])


            completionHandler(nil, error)
        }
        // finally, unregister
        self.stopObserving()
    }

        self.state = .authorizationStatePendingExternalApproval

        // calculate final url
        var params = "?scope=\(config.scope)&redirect_uri=\(config.redirectURL.urlEncode())&client_id=\(config.clientId)&response_type=code&state=\(requestIdentifier)"

        if let audienceId = config.audienceId {
            params = "\(params)&audience=\(audienceId)"
