来自ios 9

时间:2016-06-04 20:38:42

标签: python flask swift2 ios9 flask-login

我有一个Python Flask-Login网络应用程序,可以在Web浏览器中正常运行。 这是我的用户对象:

class User():

def __init__(self, user, password_hash):
    self.user = user
    self.password = password_hash

def is_authenticated(self):
    return True

def is_active(self):
    return True

def is_anonymous(self):
    return False 

def get_id(self):
    return unicode(self.user)

def get_auth_token(self, user, password):
    data = [str(self.user), self.password]
    return serializer.dumps(data, salt=serializer_secret)

我像这样登录用户(当然是在正常的用户名/密码检查之后):

user_object = User(user, password_hash)
result = login_user(user_object)

在应用程序的后续部分中,我得到了用户的ID:

user = current_user.get_id()

Web应用程序用户登录功能始终如一。 我正在尝试使用NSURLSession:

在Swift 2中创建一个iOS9应用程序
func HTTPsendRequest(request:NSMutableURLRequest, fireCallback:(String, Int, AnyObject?) -> Void) {
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { data, response, error in
        let httpStatusCode:Int
        if error != nil {
            if let httpResponse = response as? NSHTTPURLResponse {
                httpStatusCode = httpResponse.statusCode
                fireCallback("", httpStatusCode, (error!.localizedDescription) as String)
            }
        } else {
            let result = NSString(data:data!, encoding:NSASCIIStringEncoding)!
            if let httpResponse = response as? NSHTTPURLResponse {
                httpStatusCode = httpResponse.statusCode
                fireCallback(result as String, httpStatusCode, nil)
            }
        }
    })
    task.resume()
}

func HTTPPost(url:String, data:String, callback:(String, Int, AnyObject?) -> Void) {
    let url = NSURL(string:url)!
    let request = NSMutableURLRequest(URL:url)
    let data: NSData = data.dataUsingEncoding(NSUTF8StringEncoding)!
    request.HTTPBody = data
    request.HTTPMethod = "POST"
    request.addValue("application/json", forHTTPHeaderField:"Content-Type")
    request.addValue("text/plain", forHTTPHeaderField:"Accept")
    HTTPsendRequest(request, fireCallback:callback)
}

dispatch_async(dispatch_get_main_queue()) {
    HTTPPost("\(apiUrl)login", data:JSONPayload) { (response: String, httpStatusCode: Int, error: AnyObject?) -> Void in
        token = response
    }
}

此登录功能由于某种原因间歇性地不记录用户。我没有做任何不同的事情,只是反复单击应用程序上的“登录”按钮,该按钮将电子邮件和密码哈希发送到API端点。有时候它有效,有时则不然。根据Flask-Login文档:

  

默认情况下,当用户实际未登录时,   current_user设置为AnonymousUserMixin对象。它有   以下属性和方法:

     

is_active和is_authenticated是False is_anonymous是True get_id()   返回无

在尝试从Swift iOS应用程序登录后,get_id()会间歇性地返回None,我无法弄清楚原因,这让我疯狂。

我已经尝试确保使用相同的线程登录然后使用响应。我已确保在使用信号量和串行队列或仅使用dispatch_get_main_queue()异步触发需要登录响应的任何未来调用之前返回登录响应。

有没有人遇到过这个?救命啊!

----------------------------------- EDIT ----------- -----------------------

我已经运行测试并确认在swift ios应用程序的每次错误登录尝试中,烧瓶应用程序都会返回login_user(user_object)的这些值:

current_user.is_authenticated() => True
current_user.is_active() => True
current_user.is_anonymous() => False
current_user.get_id() = <user's id>

因此用户始终正确登录。 但是在随后的调用中,直接在登录后,到另一个需要用户登录的功能,就是错误所在。 这个其他函数用@login_required装饰器修饰。 如果此测试失败,则应返回401 Not Authorized,它在实际情况下会返回。但由于某种原因,当用户刚刚登录时有时会返回500,当它发生时,在日志文件中我可以看到例外情况:

File "/usr/local/lib/python2.7/site-packages/flask_login.py", line 756, in decorated_view
    elif not current_user.is_authenticated():
File "/usr/local/lib/python2.7/site-packages/flask_login.py", line 794, in _get_user
    current_app.login_manager._load_user()
File "/usr/local/lib/python2.7/site-packages/flask_login.py", line 363, in _load_user
    return self.reload_user()
File "/usr/local/lib/python2.7/site-packages/flask_login.py", line 325, in reload_user
    user = self.user_callback(user_id)
TypeError: 'NoneType' object is not callable

所以问题现在变成了,如果用户已经成功登录,为什么login_required无法从用户对象中找到用户呢?

0 个答案:

没有答案