sending accessToken to server using swift ios - ios

I am trying to use facebook ios login sdk. I get the access Token using below code. Now i want to send this token to a server so that server can validate this token by making a call to facebook server.
I am using the below code to get the accessToken , i am using swift in ios 8.
var accessToken = FBSession.activeSession().accessTokenData
When i am trying to send this token to server getting an error saying that type of accessToken is not convertible to NSString.
Please help me where i am wrong.

First, make sure that you have an open session. I use this approach in my AppDelegate:
FBSession.openActiveSessionWithAllowLoginUI(false)
Second, you can get accessToken as a string from accessTokenData:
var myToken = FBSession.activeSession().accessTokenData.accessToken
From there, you can send it to your server however you want. I tried a couple request wrappers until I settled on Net. Getting your token to your server is pretty easy if you have a library like Net so that you don't have to handle the low level network request interfaces:
func doLogin() -> Void {
let net = Net(baseUrlString: "http://myhost.com/")
let url = "auth/facebook_access_token"
let params = ["access_token": myToken]
net.GET(url, params: params, successHandler: { responseData in
let result = responseData.json(error: nil)
// Do something with whatever you got back
NSLog("result \(result)")
}, failureHandler: { error in
NSLog("Error")
})
}
Good luck! I hope I was able to help!

Related

How to implement basic web authentication in SwiftUI App for a specific web service that does not provide an API?

I will get straight to the point. Please excuse my english
So there is a website (we can call it X) which offers a service to query and fetch documents etc after logging in with your username / password
I am trying to figure out a way to, basically, provide the same service except natively through the app. The user of the app will still have to enter their username and password and then I make a request to the website and "log" in and then provide the same interface the website does after logging in but the app will be able to save the login information and be able to have some other features that would be beneficial wrt to the documents that it then fetches.
The website does not offer an api (atleast that I know of) I am struggling to figure out how to send the URL request with the username and password.
First I read about using ASAuthenticationServices but that led me to reading that you need the callback url which did not work for me (1. because I can't setup the callback url through the API and 2. because my custom app callback url did not fire)
Then I tried to use a WKWebView to embed a browser and a try to catch the details after the user logged in but still no success.
I have also read that JWT might be the solution considering that it is only a single server authentication needed
This is my code so far, I have stripped it down to basically just show the request I'm making
If anyone could shed some light as to how to perform a simple web login (to basically embed the web service and be able to use it as an app) I would really appreciate it.
Thanks
So this is where I'm at now. I'm trying to form a URLRequest and just checking whether the signin response works, should I be trying to implement a callback in a custom WKWebView ? I'm more kind of asking as to what method I should be using. Should I be researching more into JWT ? or should I be looking at using custom WKWebViews and trying to catch the callback and save the credentials etc through that or do I need to just deconstruct and send custom URLRequests in order to authenticate? thank you
import Combine
import Foundation
final class SignInDummy: ObservableObject {
#Published var username = ""
#Published var password = ""
#Published var hasError = false
#Published var isSigningIn = false
var canSignIn: Bool {
!username.isEmpty && !password.isEmpty
}
func signIn() {
guard !username.isEmpty && !password.isEmpty else {
return
}
let url = URL(string: "https:// URL to website (copy and pasted url of the login page)")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
let authData = (username + ":" + password).data(using: .utf8)!.base64EncodedString()
request.addValue("Basic \(authData)", forHTTPHeaderField: "Authorization")
isSigningIn = true
URLSession.shared.dataTask(with: request) { [weak self] data, response, error in
DispatchQueue.main.async {
if error != nil || (response as! HTTPURLResponse).statusCode != 200 {
self?.hasError = true
} else if let data = data {
do {
let signInResponse = try JSONDecoder().decode(SignInResponse.self, from: data)
print(signInResponse)
// TODO: Cache Access Token in Keychain
} catch {
print("Unable to Decode Response \(error)")
print("\(response?.mimeType)")
print("\(response.debugDescription)")
}
}
self?.isSigningIn = false
}
}.resume()
}
fileprivate struct SignInResponse: Decodable {
// MARK: - Properties
let accessToken: String
}
}

How to access JSON response in Swift using AWS API Gateway-generated iOS SDK

I have a working REST API based on this API Gateway tutorial. I'm able to successfully invoke it via the test functionality of the AWS Console; and I'm able to successfully invoke it via my simple iOS Swift 4.2 Xcode application using the iPhone XR simulator.
I know it's working via a real, live external call because I can see the Cloudwatch logs which always register a 200 response and is sending the results back to the Client.
My problem is really in understanding the Swift code, and I'm hoping that a Swift expert can help me understand how to unpack result in the code below.
Here's my code in ViewController.swift for invoking the REST API and attempting to print result to the console:
#IBAction func userInvokeApi(_ sender: UIButton) {
print("You clicked invoke api...")
let client = SVTLambdaGateClient.default()
client.calcGet(operand2: "3", _operator: "+", operand1: "5").continueWith{ (task: AWSTask?) -> AnyObject? in
if let error = task?.error {
print("Error occurred: \(error)")
return nil
}
if let result = task?.result {
// Do something with result
print("The result is... \(result)")
}
return nil
}
}
As pointed out in the comments below, I'm getting the following result because it's printing out the address of the object:
You clicked invoke api...
The result is... <AmplifyRestApiTest.Empty: 0x600002020770> {
}
(where AmplifyRestApiTest is the name of my Xcode project.)
UPDATE When I set a breakpoint on the print statement, this is what I see in the Debug pane:
UPDATE 2
When I type task?.result there are two viable properties as per this answer from the Amplify team: error and result. So, since my API responds successfully I am assuming I just don't know how to view result.
Can someone help me understand what steps I must take to access members of this class object?
Here is the corresponding method in the API Gateway-generated iOS Swift SDK code:
/*
#param operand2
#param _operator
#param operand1
return type: Empty
*/
public func calcGet(operand2: String, _operator: String, operand1: String) -> AWSTask<Empty> {
let headerParameters = [
"Content-Type": "application/json",
"Accept": "application/json",
]
var queryParameters:[String:Any] = [:]
queryParameters["operand2"] = operand2
queryParameters["operator"] = _operator
queryParameters["operand1"] = operand1
let pathParameters:[String:Any] = [:]
return self.invokeHTTPRequest("GET", urlString: "/calc", pathParameters: pathParameters, queryParameters: queryParameters, headerParameters: headerParameters, body: nil, responseClass: Empty.self) as! AWSTask<Empty>
}
I'm fairly certain this return type of Empty refers to the Empty model defined for the REST API as shown in the screenshot below. I think it's "empty" because the API doesn't alter the response from the Lambda function back to the Client. So, it's all pass-through. Indeed, the tutorial explains that the other models -- Output and Result -- are not used because it "relies on the passthrough behavior and does not use this model."
Any thoughts?

log in yii2 account using Alamofire

I'm trying to log in into account using api and POST request in Swift 3 with Alamofire library. Here is my code:
#IBAction func logInButtonClick(_ sender: Any) {
Alamofire.request(".../api/login", method: .post, parameters: ["email": "mail1#gmail.com", "password" : "qwerty"], encoding: JSONEncoding.default).responseString { (response) in
if let result = response.result.value {
print(result)
}
}
}
When I'm trying to get an access_token field (user exists and api works correctly, for sure) from this request, I am not getting it.
The fact is my api user's url is always the same (I've already read this: How to pass access token to Alamofire?) and looks like ".../api/login/" and it doesn't depend on user e-mail or username, and I don't know how I should deal with it in a such way. Thanks in advance.

How do I get to AccessToken and IdToken following successful Amazon Cognito Login from iOS

I have been using the following sample to introduce cognito login to my iOS application:
https://github.com/awslabs/aws-sdk-ios-samples/tree/master/CognitoYourUserPools-Sample
This is working well and I am at the point where I have a AWSCognitoIdentityUserPool object which I can call the currentUser() method to access the user.
What I am struggling to find is how I extract both the AccessToken and the IdToken.
In the android equivalent, the onSuccess method of the AuthenticationHandler has a CognitoUserSession argument which in turn has getIdToken() and getAccessToken().
Frustratingly, I see them output as the AuthenticationResult in json format in the output window, but I just don't know how to access them programatically?
Figured it out now:
func getSession(){
self.user?.getSession().continueOnSuccessWith { (getSessionTask) -> AnyObject? in
DispatchQueue.main.async(execute: {
let getSessionResult = getSessionTask.result
self.idToken = getSessionResult?.idToken?.tokenString
self.accessToken = getSessionResult?.accessToken?.tokenString
})
return nil
}
}

Facebook Pages API Swift

I'm new in programming in swift. I'm trying to read Facebook pages posts(wall) from a public page and show the content(images and messages) in my app without users login. I've already set up the app with Facebook SDK (plist, bridging-Header.h etc...). I know I must open a session and pass a valid access token to the Facebook server. But I can't understand how....
below my viewDidLoad
let request = "/(pageID)?fields=id,posts"
FBRequestConnection.startWithGraphPath(request, completionHandler: {(connection: FBRequestConnection!, result: AnyObject!, error: NSError!) -> Void in
if (error? != nil){
NSLog("error = \(error)")
}else{
println(result)
}
} as FBRequestHandler)
I get this error:
An open FBSession must be specified for calls to this endpoint.
com.facebook.sdk:ParsedJSONResponseKey={
body = {
error = {
code = 104;
message = "An access token is required to request this resource.";
type = OAuthException;
};
};
code = 400;
}}
i think i need to open a session in AppDelegate and so I can make the request I've also read the Facebook documentation but I haven't found the answer.
Please help me. Thank you!!!

Resources