Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
815 views
in Technique[技术] by (71.8m points)

ios - NSURLSession Authentication

I tried to use the swift code found here on the website found here, but the response is html code with the two errors: "You must enter a password!" and "You must enter a User name!" I am new to NSURLSession and tried to change the string for authentication but nothing worked to change the response. Here is my code:

 let config = NSURLSessionConfiguration.defaultSessionConfiguration()
 let userPasswordString = "[email protected]:password"
 let userPasswordData = userPasswordString.dataUsingEncoding(NSUTF8StringEncoding)
 let base64EncodedCredential = userPasswordData!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.Encoding64CharacterLineLength)
 let authString = "Basic (base64EncodedCredential)"
 config.HTTPAdditionalHeaders = ["Authorization" : authString]
 let session = NSURLSession(configuration: config)
    var running = false
        let url = NSURL(string: "https://hac.chicousd.org/")
        let task = session.dataTaskWithURL(url!) {
            (let data, let response, let error) in
            if (response as? NSHTTPURLResponse) != nil {
                let dataString = NSString(data: data!, encoding: NSUTF8StringEncoding)
                print(dataString)
            }
            running = false
        }

        running = true
        task.resume()

        while running {
            print("waiting...")
            sleep(1)
        }

And this is in the console response:

<!-- Start Error box -->
<div id="errorContainer" class="alert alert-danger" style="display:none;">
<button id="portalCloseError" type="button" class="close"> &times;</button>
<span id="errorMessage" class="error" data-pw-error="You must enter a password!" data-username-error="You must enter a User Name!"></span>
</div> <!-- End Error box -->
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There are 2 ways to sign in to a website: HTTP Authorization and form. Most website uses the later, more user-friendly login form. HTTP Authorization is only used when the website expects to interact with a user program (no, browsers don't count here).

Before you code, you need to scout the website for what form data it sends, as knowing is half the battle:

  1. Visit the school website and press Cmd + Opt + C to open the Developer's Console.
  2. Click the Network tab.
  3. Do not close this console. Go back to the website and enter your username and password as usual.

Observe what data the page sends:

Developer Console

In plain text:

checkCookiesEnabled         true
checkMobileDevice           false
checkStandaloneMode         false
checkTabletDevice           false
portalAccountUsername       email
portalAccountPassword       password
portalAccountUsernameLabel

So the username is delivered in a field called portalAccountUsername and password in portalAccountPassword. The other fields may or may not be important.

And now you can write your code:

@IBAction func login(sender: AnyObject) {
    let url = NSURL(string: "https://hac.chicousd.org/LoginParent.aspx")!

    // The form parameters
    let parameters = [
        "checkCookiesEnabled": "true",
        "checkMobileDevice": "false",
        "checkStandaloneMode": "false",
        "checkTabletDevice": "false",
        "portalAccountUsername": "username",
        "portalAccountPassword": "password"
    ]

    let bodyString = parameters
                        .map { $0 + "=" + $1 }
                        .joinWithSeparator("&")
                        .stringByAddingPercentEncodingWithAllowedCharacters(.URLQueryAllowedCharacterSet())!


    let request = NSMutableURLRequest(URL: url)
    request.HTTPMethod = "POST"
    request.HTTPBody = bodyString.dataUsingEncoding(NSUTF8StringEncoding)

    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
        guard error == nil else {
            print(error?.localizedDescription)
            return
        }
        guard let data = data else {
            print("empty data")
            return
        }

        // This is the HTML source of the landing page after login
        let html = String(data: data, encoding: NSUTF8StringEncoding)
    }
    task.resume()
}

For some reasons, I couldn't make the request until I disabled App Transport Security. Maybe resources on that website come from non-HTTPS domains.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...