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)!))
Related
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'm trying to authenticate with uber in my project, the path to go to the uber native app and then return to my application is ok. However, it is only returning the TokenString and the ExpirationDate and the refreshToken is returning as nil.
Here is my code
AuthorizationBaseViewController
class AuthorizationBaseViewController: UIViewController {
func delay(delay: Double, closure: ()->()) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(delay*Double(NSEC_PER_SEC))), dispatch_get_main_queue(), closure)
}
func showMessage(message: String) {
let alert = UIAlertController(title: nil, message: message, preferredStyle: UIAlertControllerStyle.Alert)
let okayAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil)
alert.addAction(okayAction)
self.presentViewController(alert, animated: true, completion: nil)
}
func checkError(response: Response) {
// Unauthorized
if response.statusCode == 401 {
TokenManager.deleteToken()
dispatch_async(dispatch_get_main_queue(), {
self.reset()
})
}
}
func reset() {
}
// Mark: LoginButtonDelegate
func loginButton(button: LoginButton, didLogoutWithSuccess success: Bool) {
if success {
showMessage(NSLocalizedString("Integration with uber canceled.", comment: ""))
}
}
func loginButton(button: LoginButton, didCompleteLoginWithToken accessToken: AccessToken?, error: NSError?) {
if let _ = accessToken {
print(accessToken?.tokenString)
print(accessToken?.expirationDate)
print(accessToken?.refreshToken)
showMessage(NSLocalizedString("Uber user authenticated successfully.", comment: ""))
if let url = NSURL(string: "xxxxxxxxxxxxxx") {
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
let token = AccessToken?()
let jsonObject = ["token" : (token?.tokenString)!, "refresh_token" : (token?.refreshToken)!,"expires_in" : (token?.expirationDate)!, "user_id" : "uber_uuid" , "token_type" : "Bearer"] as Dictionary <String,AnyObject>
request.HTTPBody = try? NSJSONSerialization.dataWithJSONObject(jsonObject, options: [])
NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
guard
let data = data where
error == nil &&
(response as? NSHTTPURLResponse)?.statusCode == 200
else {
print((response as? NSHTTPURLResponse)?.statusCode ?? "no status code")
print(error?.localizedDescription ?? "no error description")
return
}
print(String(data: data, encoding: NSUTF8StringEncoding) ?? "no string from data")
}.resume()
}
showMessage((error?.localizedDescription)!)
} else if let error = error {
showMessage(error.localizedDescription)
} else {
showMessage("Error")
}
}
}
LoginViewController
class ImplicitGrantLoginViewController: AuthorizationBaseViewController, LoginButtonDelegate {
/// The LoginManager to use for login
let loginManager = LoginManager(loginType: .Native)
/// The RidesClient to use for endpoints
let ridesClient = RidesClient()
// The Uber button to use for UI
var uberLoginButton: LoginButton?
// The Uber Scopes
var uberScopes: [RidesScope]?
#IBOutlet weak var logoutBgView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
//UberScopes to get authentication
uberScopes = [.History, .Profile, .HistoryLite,.Places, .RideWidgets]
uberLoginButton = LoginButton(frame: CGRectZero,scopes:uberScopes! ,loginManager: loginManager)
// Uber Login Button Creation
let loginButton = LoginButton(frame: CGRectZero, scopes: uberScopes!, loginManager: loginManager)
loginButton.presentingViewController = self
loginButton.delegate = self
loginButton.frame = logoutBgView.bounds
loginButton.autoresizingMask =
[.FlexibleWidth, .FlexibleHeight]
logoutBgView.addSubview(loginButton)
}
Basically, if the refresh Token is returning to my application, a POST request is made along with the TokenString and the ExpirationDate
When authentication is done, before displaying the authorization view it appears the following error
MyApp[18136:615342] -canOpenURL: failed for URL: "uberauth://connect?third_party_app_name=MyApp &callback_uri_string=xxxxxx &client_id=xxxxxxxxxx &login_type=default&scope=history%20profile%20history_lite%20places%20ride_widgets&sdk=ios&sdk_version=0.6.0
Even with this error, the screen to authorize the scopes is displayed and when I hit Allow I see the return in the debug area however the app crashes due to the refreshtoken is nil and HTTP request not receiving it.
Error when App Crashes due to refreshtoken is nil
I already checked the plist file and fill according uber documentation/github repository's. Callback URI, LSApplicationQuerieScheme,Client ID,DisplayName it is correct.
So reading through your question I see a few issues. It looks like you are trying to do Native login via the Uber app, which should return you an access token and a refresh token. If you are not doing Native login, then you will not get a refresh token, and that would be why it is nil.
The error message you listed:
MyApp[18136:615342] -canOpenURL: failed for URL:
"uberauth://connect?third_party_app_name=MyApp
&callback_uri_string=xxxxxx &client_id=xxxxxxxxxx
&login_type=default&scope=history%20profile%20history_lite%20places%20ride_widgets&sdk=ios&sdk_version=0.6.0
Means that you have not added uberauth into the plist of your app under LSApplicationQueriesSchemes. I noticed that you referred to it as LSApplicationQuerieScheme which is misspelled. So that might be your problem there.
You say that the authorization code screen is still shown, which makes me think that it is falling back to Implicit Grant in a webview, which will not return a refresh token to you.
Additionally, in the code you provided where you are making your post request, you never use the access token you get back:
let token = AccessToken?()
let jsonObject = ["token" : (token?.tokenString)!,
"refresh_token" : (token?.refreshToken)!,
"expires_in" : (token?.expirationDate)!,
"user_id" : "uber_uuid" ,
"token_type" : "Bearer"] as Dictionary <String,AnyObject>
You initialize a new empty AccessToken and then force unwrap several optional values on that token (not the one you got back from the initial login). So those values are almost certainly nil, and the force unwrap is causing the crash
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)
}
}
I am trying to get a sample Tumblr client up and running. I am using the OAuth Swift library to do my OAuth.
Right now my project has one button. This button checks to see if OAuth has been authorized or not. If it is, then it is set up to post some hard coded data to a test Tumblr account I set up.
I am getting this output on the console:
Top of authorizeWithCallbackURL
OAuth successfully authorized
Request error
Server Response:
{"meta":{"status":401,"msg":"Not Authorized"},"response":[]}
It appears that my token is accepted and an OAuth token is generated, but for some reason it is not being included in the POST request I am trying to call once I have been authorized.
This is my code with the appropriate redactions:
import UIKit
import OAuthSwift
class ViewController: UIViewController {
var session:NSURLSession!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func postToTumblr(sender: AnyObject) {
let oauthSwift = OAuth1Swift(
consumerKey: "***",
consumerSecret: "***",
requestTokenUrl: "https://www.tumblr.com/oauth/request_token",
authorizeUrl: "https://www.tumblr.com/oauth/authorize",
accessTokenUrl: "https://www.tumblr.com/oauth/access_token"
)
oauthSwift.authorizeWithCallbackURL(NSURL(string: "tumblrsampleapp://oauth-callback")!,
success: { credential, response in
// post to Tumblr
print("OAuth successfully authorized")
// Configure NSURLSession
let config = NSURLSessionConfiguration.ephemeralSessionConfiguration()
config.HTTPAdditionalHeaders = ["Authorization":credential]
self.session = NSURLSession(configuration: config)
// Post hardcoded data to Tumblr
let request = self.request("consumerSecretKey&\(credential.oauth_token_secret)")
let uploadTask = self.session.dataTaskWithRequest(request!) { (responseData, response, error) in
// Check on some response headers (if it's HTTP)
if let httpResponse = response as? NSHTTPURLResponse {
switch httpResponse.statusCode {
case 200..<300:
print("Success")
case 400..<500:
print("Request error")
case 500..<600:
print("Server error")
case let otherCode:
print("Other code: \(otherCode)")
}
}
// Do something with the response data
if let responseData = responseData,
responseString = String(data: responseData, encoding: NSUTF8StringEncoding) {
print("Server Response:")
print(responseString)
}
// Do something with the error
if let error = error {
print(error.localizedDescription)
}
}
uploadTask.resume()
}, failure: {(error:NSError!) -> Void in
self.presentAlert("Error", message: error!.localizedDescription)
})
}
func request(credential:String) -> NSURLRequest? {
guard let url = NSURL(string: "https://api.tumblr.com/v2/blog/{hostname}/post") else {return nil}
let request = NSMutableURLRequest(URL: url)
let requestData = self.buildRequestData()
request.HTTPMethod = "POST"
request.HTTPBody = requestData
let postDataLengthString = String(format:"%d", requestData.length)
let credentialString = String(format:"%d", credential)
request.setValue(postDataLengthString, forHTTPHeaderField:"Content-Length")
request.setValue(credentialString, forHTTPHeaderField: "Authorization")
return request
}
func buildRequestData() -> NSData {
// Getting these parameters from this site:
// https://www.tumblr.com/docs/en/api/v2#posting
// It looks like there are a bunch of optional paramters
let requestDictionary = [
["type":"text"],
["title": "Hello, World!"],
["body": "Hello world. This is my first post."]
]
let data = try? NSJSONSerialization.dataWithJSONObject(requestDictionary, options: NSJSONWritingOptions())
return data!
}
func presentAlert(title: String, message: String) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
}
I believe the issue involves the request function not generating the header properly. I did not see anything in the Tumblr documentation saying that I need to include an authorization token with the request, so I am assuming that they are assuming I am supposed to know that.
Any insight as to what I am doing wrong would be greatly appreciated. Thanks!
I am using OAuthSwift and whenever I run this function
func doOAuthTwitter(){
let oauthswift = OAuth1Swift(
consumerKey: "...",
consumerSecret: "...",
requestTokenUrl: "https://api.twitter.com/oauth/request_token",
authorizeUrl: "https://api.twitter.com/oauth/authorize",
accessTokenUrl: "https://api.twitter.com/oauth/access_token"
)
oauthswift.authorize_url_handler = WebViewController()
oauthswift.authorizeWithCallbackURL( NSURL(string: "oauth-swift://oauth-callback/twitter")!, success: {
credential, response in
self.showAlertView("Twitter", message: "auth_token:\(credential.oauth_token)\n\noauth_toke_secret:\(credential.oauth_token_secret)")
var parameters = Dictionary<String, AnyObject>()
oauthswift.client.get("https://api.twitter.com/1.1/statuses/home_timeline.json", 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)
}
)
}
the function seems to run until after this point
oauthswift.authorize_url_handler = WebViewController()
authorizeWithCallbackURL doesn't even start and the jsonDict does not print. I've tried my access codes through the OAuthSwift demo, and it works fine with the tableView, printing out the JsonDict. I have no idea why authorizeWithCallbackURL goes completely ignored when I use it outside of the demo.