oauth2.0 - 带有密码授权类型的令牌访问请求,带有ios / swift 2客户端

时间:2016-01-12 23:54:28

标签: oauth-2.0 swift2

我有自己的web应用程序,使用laravel作为后端,工作正常。

现在,我开始编写IOS应用程序(IOS 9,Xcode 7,Swift 2),并希望将其连接到我的Web应用程序数据库,以便我可以使用API​​进行查询。

我遇到的第一步是用户通过IOS应用程序连接到Web应用程序数据库的登录名/密码。

我已在我的网络应用上安装了oauth 2.0配置并使用密码授予类型。使用Postman测试,我可以使用x-www-form-urlencoded中的以下参数获取访问令牌:

  • grant_type =密码
  • client_id = f3d259ddd3ed8ff3843839b
  • client_secret = 4c7f6f8fa93d59c45502c0ae8c4a95b
  • username = user1@test.com
  • 密码= 123456

现在,我想使用IOS应用程序中的这些凭据访问此Web应用程序的数据库。

我在视图控制器中创建了一个登录表单。当我点击登录按钮时,我按如下方式启动IBAction:

    @IBAction func login(sender: UIButton){

    let myURL = NSURL(string: "http://myWebApplication.com/oauth/access_token")!
    let request = NSMutableURLRequest(URL: myURL)
    request.HTTPMethod = "POST"
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    request.setValue("application/json", forHTTPHeaderField: "Accept")
    let bodyStr:String = "grant_type=password&client_id=f3d259ddd3ed8ff3843839b&client_secret=4c7f6f8fa93d59c45502c0ae8c4a95b&username=user1@test.com&password=123456"
    request.HTTPBody = bodyStr.dataUsingEncoding(NSUTF8StringEncoding)
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
        data, response, error in

        // Your completion handler code here
    }
    task.resume()


}

但什么都没发生。

你可以告诉我我哪里错了吗?

我花了几个小时搜索解决方案,上面的代码是此搜索的结果。不幸的是,还不够。

最重要的是,存储Web应用程序将返回并使用它的访问令牌的下一步是什么,以便我可以发送与此特定用户相关的查询?

提前感谢您的帮助

2 个答案:

答案 0 :(得分:1)

我遇到了同样的问题..主要来自Cristina Moulton的iOS with REST API一书,希望它有所帮助。

试试这个:#使用Alamofire& SwiftyJSON#

    func loginUser() {

    var code:String?
    var accessToken:String?

    let path:String = EndPoints.kRestEndpoint + EndPoints.kToken

    let parameters:[String:String] = ["grant_type": "password","client_id": "tes5@test.com.br", "client_secret": "123456"]
    let headers:[String:String] = ["Content-Type": "application/x-www-form-urlencoded","Accept": "application/json"]

    Alamofire.request(.POST, path, parameters: parameters, encoding: .URL, headers: headers).responseString { response in

      // Handle response to extract the OAuth Token
      if let error = response.result.error {
        print(error)
        return
      }

      // The access token + type
      print(response.result.value)

      if let receivedResults = response.result.value, jsonData = receivedResults.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) {
        let jsonResults = JSON(data: jsonData)

        for (key, value) in jsonResults {
          switch key {
          case "access_token":
            if let token = value.string {
              code = token
            }
          case "token_type":
            if let type = value.string {
              accessToken = "\(type) \(code!)"
            }
          case "expires_in":
            // Handle expiration
            print("It has expiration")
          default:
            print("got more than I expected from the OAuth token exchange")
            print(key)
          }
        }
        print("AccessToken: \(accessToken!)")
      } //End of receivedResults

      let defaults = NSUserDefaults.standardUserDefaults()
      defaults.setBool(true, forKey: "loadingOAuthToken")
    }
  }

答案 1 :(得分:1)

感谢Frederico的帮助。

我最终使用KeychainWrapper管理这种方式(管理敏感信息的钥匙串非常有用)。

如果有任何评论,请告诉我:

    @IBAction func loginButtonTapped(sender: UIButton) {
    self.emailTextField.resignFirstResponder()
    self.passwordTextField.resignFirstResponder()

    if (self.emailTextField.text == "" || self.passwordTextField.text == "") {
        let alertView = UIAlertController(title: "Login failed",
        message: "Wrong username or password." as String, preferredStyle:.Alert)
        let okAction = UIAlertAction(title: "Try Again!", style: .Default, handler: nil)
        alertView.addAction(okAction)
        self.presentViewController(alertView, animated: true, completion: nil)
        return
    }

    // Check if the user entered an email
    if let actualUsername = self.emailTextField.text {

        // Check if the user entered a password
        if let actualPassword = self.passwordTextField.text {

            // Build the body message to request the token to the web app
            self.bodyStr = "grant_type=password&client_id=f3d259ddd3ed8ff3843839b&client_secret=4c7f6f8fa93d59c45502c0ae8c4a95b&username=" + actualUsername + "&password=" + actualPassword

            // Setup the request
            let myURL = NSURL(string: "http://test.com/oauth/access_token")!
            let request = NSMutableURLRequest(URL: myURL)
            request.HTTPMethod = "POST"
            request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
            request.setValue("application/json", forHTTPHeaderField: "Accept")
            request.HTTPBody = bodyStr.dataUsingEncoding(NSUTF8StringEncoding)!

            let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
                (data, response, error) -> Void in
                if let unwrappedData = data {

                    do {

                        // Convert the Json object to an array of dictionaries
                        let tokenDictionary:NSDictionary = try NSJSONSerialization.JSONObjectWithData(unwrappedData, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary

                        // Get the token
                        let token:String = tokenDictionary["access_token"] as! String

                        // Keep record of the token
                        let saveToken:Bool = KeychainWrapper.setString(token, forKey: "access_token")

                        // Dismiss login view and go to the home view controller
                        self.dismissViewControllerAnimated(true, completion: nil)

                    }
                    catch {
                        // Wrong credentials
                        // Reset the text fields
                        self.emailTextField.text = ""
                        self.passwordTextField.text = ""

                        // Setup the alert
                        let alertView = UIAlertController(title: "Login failed",
                            message: "Wrong username or password." as String, preferredStyle:.Alert)
                        let okAction = UIAlertAction(title: "Try Again!", style: .Default, handler: nil)
                        alertView.addAction(okAction)
                        self.presentViewController(alertView, animated: true, completion: nil)
                        return
                    }
                }
            }
            task.resume()
        }
    }
}