I'm trying to create a client (in a private pod) to connect to garmin API (OAuth1) and i've some problem to do it. I'm using OAuthSwift and OAuthSwiftAlamofire
First i'm trying to get all the authorization,
let oauthswift = OAuth1Swift(
consumerKey: "*****************",
consumerSecret: "****************",
requestTokenUrl: "http://connectapitest.garmin.com/oauth-service-1.0/oauth/request_token",
authorizeUrl: "http://connecttest.garmin.com/oauthConfirm",
accessTokenUrl: "http://connectapitest.garmin.com/oauth-service-1.0/oauth/access_token"
)
oauthswift.authorizeURLHandler = SafariURLHandler(viewController: self, oauthSwift: oauthswift)
let _ = oauthswift.authorize(
withCallbackURL: URL(string: "https://www.****.co/api/v2/garminCallback")!,
success: { credential, response, parameters in
print("Success")
print(credential.oauthToken)
print(credential.oauthTokenSecret)
print(credential.oauthVerifier)
},
failure: { error in
print("Error")
print(error.localizedDescription)
})
AppDelegate:
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
if (url.host == "oauth-callback") {
OAuthSwift.handle(url: url)
}
return true
}
So, this part of code open the connection page of garmin in safari, i use my account mail/pwd to connect and that's all. The callback never sucess, or never fail. So i can't access to my credentials. It's like authorize(withCallBackURL...) don't wait the callBack et never get the information in the URL (like oauth-idenfitifier).
I'dont understand why, if you have an idea thank's.
I'm Sharing my Code that's working for me
// create an instance of oAuth and retain it
let oauthSwift = OAuth1Swift(
consumerKey: "*******",
consumerSecret: "*******",
requestTokenUrl: "https://connectapi.garmin.com/oauth-service/oauth/request_token",
authorizeUrl: "https://connect.garmin.com/oauthConfirm",
accessTokenUrl: "https://connectapi.garmin.com/oauth-service/oauth/access_token"
)
// add safari as authorized URL Handler
oauthSwift.authorizeURLHandler = SafariURLHandler(viewController: self, oauthSwift: oauthSwift)
// set redirection URL
guard let redirectURL = URL(string: "oauth-swift://garmin-callback") else { return }
// add callback url to authorized url
oauthSwift.addCallbackURLToAuthorizeURL = true
// authorized the request
oauthSwift.authorize(withCallbackURL: redirectURL, success: { (credentials, response, parameters) in
print(response)
}, failure: { (error) in
print(error)
})
//authorize call has been changed to below
oauthSwift.addCallbackURLToAuthorizeURL = true
oauthSwift.authorize(withCallbackURL: redirectURL) { result in
switch result {
case .success(let (req, response, res)):
print("response=", response ?? "no")
print("req=", req ?? "no")
print("res=", res ?? "no")
print("dataString=",response?.dataString())
if let secrect = res["oauth_token_secret"] as? String{
self.garminAccessTokenSecret = secrect
}
if let token = res["oauth_token"] as? String{
self.garminAccessToken = token
}
case .failure(let error):
print(error.description)
}
}
Related
**I am Facing essue while implemention of apple sign in i got the guideline which is 5.1.1 . i want to revoke the logged in user. i got apple auth token while implemention apple sign in i got refresh token through jwt cloud function when i revoke it give me error...
could not handle the request i got how we can fix?
**
code where i have maked the cloud function.
const functions = require("firebase-functions");
// The Firebase Admin SDK to access Firestore.
const admin = require("firebase-admin");
admin.initializeApp();
function makeJWT() {
const jwt = require("jsonwebtoken");
const fs = require("fs");
const privateKey = fs.readFileSync("AuthKey_xxxxxxxxx.p8");
const token = jwt.sign({
iss: "xxxxxxxxxxx",
iat: Math.floor(Date.now()/1000),
exp: Math.floor(Date.now()/1000)+120,
aud: "https://appleid.apple.com",
sub: "xxx.xxxxxxxx.xxxxxxx",
}, privateKey, {
algorithm: "ES256",
header: {
alg: "ES256",
kid: "xxxxxxxxxxxx",
}});
return token;
}
exports.getRefToken = functions.https.onRequest(async (request, response) => {
// import the module to use
const axios = require("axios");
const qs = require("qs");
const code = request.query.code;
const clientSecret = makeJWT();
const data = {
"code": code,
"client_id": "xxx.xxxxxxxx.xxxxxxxxxxxx",
"client_secret": clientSecret,
"grant_type": "authorization_code",
};
return axios.post("https://appleid.apple.com/auth/token", qs.stringify(data), {
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
})
.then(async (res) => {
response.send(res.data.refresh_token);
});
});
exports.revokeToken = functions.https.onRequest( async (request, response) => {
// import the module to use
const axios = require("axios");
const qs = require("qs");
const refreshToken = request.query.refresh_token;
const clientSecret = makeJWT();
const data = {
"token": refreshToken,
"client_id": "xxx.xxxxxxx.xxxxxxxxx",
"client_secret": clientSecret,
"token_type_hint": "refresh_token",
};
return axios.post("https://appleid.apple.com/auth/revoke", qs.stringify(data), {
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
})
.then(async (res) => {
console.log(res.data);
}).catch((error) => {
console.log(error);
});
});
//Apple Sign In
guard let nonce = currentNonce else {
fatalError("Invalid state: A login callback was received, but no login request was sent.")
}
guard let appleIDToken = appleIDCredential.identityToken else {
print("Unable to fetch identity token")
return
}
guard let idTokenString = String(data: appleIDToken, encoding: .utf8) else {
print("Unable to serialize token string from data: \(appleIDToken.debugDescription)")
return
}
// Initialize a Firebase credential.
let credential = OAuthProvider.credential(withProviderID: "apple.com",
idToken: idTokenString,
rawNonce: nonce)
// Sign in with Firebase.
Auth.auth().signIn(with: credential) { (authResult, error) in
if error == nil{
print("---------------------------SignInInfo---------------------------")
print("User : - \(appleIDCredential.user)")
print("idTokenString : - \(idTokenString)")
print("email : - \(appleIDCredential.email)")
let authorizationCode = appleIDCredential.authorizationCode
let authCodeString = String(data: authorizationCode!, encoding: .utf8)
print("AuthCode : - \(authCodeString!)")
print("------------------------------RefreshTokenGetApi-------------------------")
let url = URL(string: "htttps://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxxx?getRefToken?code=\(authCodeString!)".addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? "https://apple.com")!
print(url)
let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
if error == nil{
if let data = data {
print(data)
let refreshToken = String(data: data, encoding: .utf8) ?? ""
print(refreshToken)
UserDefaults.standard.set(refreshToken, forKey: "refreshToken")
UserDefaults.standard.synchronize()
DispatchQueue.main.async {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "AppleSignOutWithFirebase") as! AppleSignOutWithFirebase
self.navigationController?.pushViewController(vc,animated: true)
}
}
}else{
print(error?.localizedDescription)
}
}
task.resume()
print("---------------------refreshTokenApiEnd---------------------")
}else{
print(error?.localizedDescription)
}
}
}
//**apple Revoke**
func removeAccount() {
let token = UserDefaults.standard.string(forKey: "refreshToken")
if let token = token {
let SignOuturl = URL(string: "htttps://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxxx?refreshToken=\(token)".addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? "https://apple.com")!
print(SignOuturl)
let task = URLSession.shared.dataTask(with: SignOuturl) {(data, response, error) in
guard data != nil else { return }
let firebaseAuth = Auth.auth()
do {
try firebaseAuth.signOut()
print("Yes Signed Out!")
} catch let signOutError as NSError {
print("Error signing out: %#", signOutError)
}
}
task.resume()
}
}
}
Here is my code to auth with Instagram using safariviewcontroller.
Everything is okay, but web page in SFVC is too big, why?
func doOAuthInstagram(_ serviceParameters: [String:String]){
let oauthswift = OAuth2Swift(
consumerKey: serviceParameters["consumerKey"]!,
consumerSecret: serviceParameters["consumerSecret"]!,
authorizeUrl: "https://api.instagram.com/oauth/authorize",
responseType: "code"
)
oauthswift.allowMissingStateCheck = true
oauthswift.authorizeURLHandler = SafariURLHandler(viewController: self, oauthSwift: oauthswift)
guard let rwURL = URL(string: "https://badyi.github.io/") else { return }
oauthswift.authorize(withCallbackURL: rwURL, scope: "user_profile,user_media", state: "1"){ result in
switch result {
case .success(let (credential, _, _)):
self.showTokenAlert(name: serviceParameters["name"], credential: credential)
case .failure(let error):
print(error.description)
}
}
}
Result
Thanks in advance.
I am using oAuth2.0 for reading email from my Gmail account. And here is my code
oauthswift = OAuth2Swift(
consumerKey: "242468529977-xxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com",
consumerSecret: "GfGVl_xxxxxxxxxxmjnAX",
authorizeUrl: "https://accounts.google.com/o/oauth2/auth",
accessTokenUrl: "https://accounts.google.com/o/oauth2/token",
responseType: "code"
)
oauthswift?.allowMissingStateCheck = true
let _ = oauthswift?.authorize(
withCallbackURL: URL(string: "urn:ietf:wg:oauth:2.0:oob")!, scope: "https://www.googleapis.com/auth/gmail.metadata", state: "",
success: { credential, response, parameters in
let parameters = Dictionary<String, AnyObject>()
// Multi-part upload
print(credential)
print(response)
},
failure: { error in
print("ERROR: \(error.localizedDescription)")
}
)
but after I allow permission it is showing me this screen
and says 'Please copy this code and switch to application and paste it there.' but I don't know where to paste code.
Please Update Your code with mine one and replace secret with your key.i'm using OAuthSwift library in my project. Also Don't forgot to add URL Type Schemes in your project. and Make Role as Editor
let kClientID = ""
func doOAuthGoogle(){
let oauthswift = OAuth2Swift(
consumerKey: kClientID,
consumerSecret: "",
authorizeUrl: "https://accounts.google.com/o/oauth2/auth",
accessTokenUrl: "https://accounts.google.com/o/oauth2/token",
responseType: "code"
)
// For googgle the redirect_uri should match your this syntax: your.bundle.id:/oauth2Callback
self.oauthswift = oauthswift
oauthswift.authorizeURLHandler = getURLHandler()
// in plist define a url schem with: your.bundle.id:
let _ = oauthswift.authorize(
withCallbackURL: URL(string: "com.cearsinfotech.GmailAttachements:/oauth2Callback")!, scope: "https://www.googleapis.com/auth/gmail", state: "GMAIL",
success: { credential, response, parameters in
// self.showTokenAlert(name: "Gmail", credential: credential)
print(credential.oauthToken)
let jsonDict = try? response?.jsonObject()
print("SUCCESS: \(jsonDict)")
print(parameters)
let _ = oauthswift.client.get("https://www.googleapis.com/gmail/v3/about", success: { response in
let jsonDict:NSDictionary = try! response.jsonObject() as! NSDictionary
print("SUCCESS: \(jsonDict)")
if let arrayMessages = jsonDict.value(forKey:"messages") as? NSArray{
let dict = arrayMessages[2] as! NSDictionary
let id = dict.value(forKey: "id") as! String
let _ = oauthswift.client.get("https://www.googleapis.com/gmail/v1/users/me/messages/\(id)", success: { response in
let jsonDict:NSDictionary = try! response.jsonObject() as! NSDictionary
print("SUCCESS: \(jsonDict)")
if let payload = jsonDict.value(forKey: "payload") as? NSDictionary
{
print(payload)
if let parts = payload.value(forKey: "parts") as? NSArray
{
print(parts)
let partDict = parts[0] as! NSDictionary
if let body = partDict.value(forKey: "body") as? NSDictionary
{
print(body)
}
}
}
}, failure: { error in
print(error)
})
}
}, failure: { error in
print(error)
})
},
failure: { error in
print("ERROR: \(error.localizedDescription)")
//code=4/pYAZQTq2Y5nz0g0hZSAC4wC3AuQLzdJlW6pVjjXDFHM#
}
)
}
You must have to USE Handler Method
//MARK:- Get URL -
func getURLHandler() -> OAuthSwiftURLHandlerType {
guard let type = self.formData.data?.handlerType else {
return OAuthSwiftOpenURLExternally.sharedInstance
}
switch type {
case .external :
return OAuthSwiftOpenURLExternally.sharedInstance
case .`internal`:
if internalWebViewController.parent == nil {
self.addChildViewController(internalWebViewController)
}
return internalWebViewController
case .safari:
#if os(iOS)
if #available(iOS 9.0, *) {
let handler = SafariURLHandler(viewController: self, oauthSwift: self.oauthswift!)
handler.presentCompletion = {
print("Safari presented")
}
handler.dismissCompletion = {
print("Safari dismissed")
}
return handler
}
#endif
return OAuthSwiftOpenURLExternally.sharedInstance
}
}
Go to authorization.py (path: .../python2.7/site-packages/pygsheets/authorization.py)
Currently, the code = input('Enter the authorization code:')
change to
code = 'the code shown in the google page which ask you to copy'
I built a AppAuth test app for android using an Azure AD tenant and it works ok. Now I am trying to the same with iOS (Swift 4) and failing when trying to exchange an access code for access token. No error is returned, I do get an idToken but no accessToken or refreshToken. No other errors. Not sure what is going on. Without an access token I can't query the graph. I am using Azure AD v2. Here are some pieces of my code:
func appAuthAuthorize(authConfig: AuthConfig) {
let serviceConfiguration = OIDServiceConfiguration(
authorizationEndpoint: NSURL(string: authConfig.authEndPoint)! as URL,
tokenEndpoint: NSURL(string: authConfig.tokenEndPoint)! as URL)
let request = OIDAuthorizationRequest(configuration: serviceConfiguration, clientId: authConfig.clientId, scopes: [OIDScopeOpenID, OIDScopeProfile], redirectURL: NSURL(string: authConfig.redirectUri)! as URL, responseType: OIDResponseTypeCode, additionalParameters: nil)
doAppAuthAuthorization(authRequest: request)
}
func doAppAuthAuthorization(authRequest: OIDAuthorizationRequest) {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.currentAuthorizationFlow = OIDAuthorizationService.present(authRequest, presenting: self, callback: {
(authorizationResponse, error) in
if (authorizationResponse != nil) {
self.authState = OIDAuthState(authorizationResponse: authorizationResponse!)
self.logMessage(message: "Got authorization code: \(String(describing: self.authState?.lastAuthorizationResponse.authorizationCode))")
self.doTokenRequest()
} else {
self.authState = nil
self.logMessage(message: "Authorization error: \(String(describing: error?.localizedDescription))")
}
})
}
func doTokenRequest() {
let tokenExchangeRequest = authState?.lastAuthorizationResponse.tokenExchangeRequest()
OIDAuthorizationService.perform(tokenExchangeRequest!) {
tokenResponse, error in
if tokenResponse == nil{
self.logMessage(message: "Token exchange error: \(error!.localizedDescription)")
} else {
self.authState?.update(with: tokenResponse!, error: error)
self.saveState()
self.logMessage(message: "Received token response with accesToken: \(tokenResponse!.idToken!)")
self.logMessage(message: "Received token response with accesToken: \(tokenResponse!.refreshToken!)")
self.logMessage(message: "Received token response with accesToken: \(tokenResponse!.accessToken!)")
self.retrieveUserProfile()
}
self.authState?.update(with: tokenResponse, error: error)
}
}
Got the answer. The problem is that depending on the authorization server, one has to use scopes defined for that server. In the code above, I used the default OpenId scopes of OIDScopeOpenID and OIDScopeProfile. As soon as I changed this to Azure AD scope of User.Read, everything started working correctly. So here is the net change to the code in function appAuthAuthorize:
func appAuthAuthorize(authConfig: AuthConfig) {
let serviceConfiguration = OIDServiceConfiguration(
authorizationEndpoint: NSURL(string: authConfig.authEndPoint)! as URL,
tokenEndpoint: NSURL(string: authConfig.tokenEndPoint)! as URL)
let request = OIDAuthorizationRequest(configuration: serviceConfiguration, clientId: authConfig.clientId, scopes: ["User.Read"], redirectURL: NSURL(string: authConfig.redirectUri)! as URL, responseType: OIDResponseTypeCode, additionalParameters: nil)
doAppAuthAuthorization(authRequest: request)
}
I'm using OAuthSwift, it works perfectly, but when I click on my Login button, it opens a new Safari page. I would like to open the URL in-app, but I'm beginning and I don't know how do that.
My code :
#IBAction func loginButton(sender: AnyObject) {
doOAuthDribbble()
}
func doOAuthDribbble(){
let oauthswift = OAuth2Swift(
consumerKey: Dribbble["consumerKey"]!,
consumerSecret: Dribbble["consumerSecret"]!,
authorizeUrl: "https://dribbble.com/oauth/authorize",
accessTokenUrl: "https://dribbble.com/oauth/token",
responseType: "code"
)
oauthswift.authorizeWithCallbackURL( NSURL(string: "dribs://oauth-callback/dribbble")!, scope: "public+write+comment+upload", state: "", success: {
credential, response in
// Get User
var parameters = Dictionary<String, AnyObject>()
oauthswift.client.get("https://api.dribbble.com/v1/user?access_token=\(credential.oauth_token)", parameters: parameters,
success: {
data, response in
let jsonDict: AnyObject! = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil)
println(jsonDict)
}, failure: {(error:NSError!) -> Void in
println(error)
})
}, failure: {(error:NSError!) -> Void in
println(error.localizedDescription)
})
}
My Login Page
then, the new safari page
In viewDidLoad() of your WebViewController.swift
myUrl = someurl
myWebView.loadRequest(NSURLRequest(URL: NSURL(string: myUrl)!))