我有一个使用 UserDefaults 存储用户数据(邮件和密码)的应用程序。一旦用户发送此信息,下次他/她打开应用程序时,应用程序不应显示注册视图(只要记录了用户数据)。
我认为这可以通过 Session 来完成,但我如何告诉应用程序只显示一次注册视图(或者当需要更改信息时)?这方面的一个例子可能是 Facebook 应用程序:您必须登录,当您再次打开应用程序时,所有内容都已加载(主屏幕)。
我的应用程序通过 PHP 将信息发送到域,因此 PHP 会话可能会有所帮助。
我有一个使用 UserDefaults 存储用户数据(邮件和密码)的应用程序。一旦用户发送此信息,下次他/她打开应用程序时,应用程序不应显示注册视图(只要记录了用户数据)。
我认为这可以通过 Session 来完成,但我如何告诉应用程序只显示一次注册视图(或者当需要更改信息时)?这方面的一个例子可能是 Facebook 应用程序:您必须登录,当您再次打开应用程序时,所有内容都已加载(主屏幕)。
我的应用程序通过 PHP 将信息发送到域,因此 PHP 会话可能会有所帮助。
您可以在应用程序中执行逻辑didFinishLaunchingWithOptions
func application(_ application: UIApplication, didFinishLauchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
guard let email = UserDefaults.standard.value(forKey: "email"), let password = UserDefaults.standard.value(forKey: "password") else {
// Not set up yet
showRegistration()
return true
}
// Already signing up
showLoginView()
return true
}
有几种类型的身份验证,特别是当您处理移动应用程序和 API 时,您正在处理令牌。它通常是这样进行的:
您使用 API 开发人员或所有者为您的应用创建的clientSecret 和 clientId发送您的用户名和密码,以将其连接到服务器。示例代码:
func loginUser(email:String, pass:String, completion:@escaping (_ status:Bool, _ error:Error?, _ msg:String?) ->())
{
//Get Api keys from plist file then send login request
helper.getApiKeys { (id, key) in
let parameters = [
"grant_type":"password",
"client_id":id,
"client_secret":key,
"username":email,
"password":pass,
"scope":""
] as [String : Any]
let header = [
"Content-Type":"application/json"
]
Alamofire.request(loginUserURL!, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: header)
.validate(statusCode: 200..<300)
.responseJSON { (response) in
switch response.result {
case .success( _):
let json = response.result.value!
let swiftyJson = JSON(json)
guard let expires = swiftyJson["expires_in"].double else {
return
}
let accessToken = swiftyJson["access_token"].stringValue
let refreshToken = swiftyJson["refresh_token"].stringValue
self.helper.setToken(expires: expires, aToken: accessToken, rToken: refreshToken)
completion(true, nil, nil)
case .failure(let err):
//print(err)
if response.response?.statusCode == 401 {
completion(false,err,"Invalid Username or Password")
} else {
completion(false, err, "Error Logging In")
}
}
}
}
}
您在闭包函数中收到我构建了一个“访问令牌”、“刷新令牌”和一个“到期时间”
您在应用程序中保存令牌和到期时间UserDefaults
,并将用户转到登录页面。示例代码:
//Save token in userdefaults
func setToken(expires:Double, aToken:String, rToken:String) {
//Change to expiry unix timeinterval date
let expiryTime = Date().timeIntervalSince1970 + expires
let userDefaults = UserDefaults.standard
userDefaults.set(expiryTime, forKey: "expires_in")
userDefaults.set(aToken, forKey: "access_token")
userDefaults.set(rToken, forKey: "refresh_token")
}
然后在每次应用程序进入前台时,您都会检查用户是否已通过身份验证。这意味着您将检查是否有令牌保存在令牌UserDefaults
的到期时间根据今天的时间戳仍然有效,如果它是由于到期您可以刷新您的令牌。示例代码:
//Get tokens
private func getTokens (completion:(_ expires:TimeInterval?, _ accessToken:String?, _ refreshToken: String?) ->())
{
let userDefaults = UserDefaults.standard
let access = userDefaults.string(forKey: "access_token")
let refresh = userDefaults.string(forKey: "refresh_token")
let expiry = userDefaults.double(forKey: "expires_in")
if (access != nil && refresh != nil) {
completion(expiry, access, refresh)
} else {
completion(nil,nil,nil)
}
}
//Check if user is already Authenticated
func isAuth() -> Bool {
var status = false
var apiId = Int()
var apiKey = String()
//Get tokens and test expiry time
getTokens { (expiry, accessToken, refreshToken) in
if (accessToken != nil && refreshToken != nil) {
//If due to expiry then refresh
if ((expiry! - Date().timeIntervalSince1970) < 2592000 /* 1 month */ ) {
print(expiry!); print(Date().timeIntervalSince1970)
getApiKeys(completion: { (id, key) in
apiId = id
apiKey = key
})
refresh(refreshToken: refreshToken!, grantType: "refresh_token", clientId: apiId, clientSecret: apiKey, scope: "", completion: { (stat, err, msg) in
if stat {
status = true
} else {
status = false
}
})
} else {
status = true
}
} else {
status = false
}
}
if status {
return true
} else {
return false
}
}
所以这意味着用户始终处于登录状态,并且永远不会被发送到登录视图控制器,除非isAuth()
函数返回 false。在我的情况下,过期日期或用户刚刚注销,我删除了他的令牌。示例代码:
//Delete token for loggin out
func logOut() {
let userDefaults = UserDefaults.standard
userDefaults.removeObject(forKey: "expires_in")
userDefaults.removeObject(forKey: "access_token")
// Segue user to login page
}