【问题标题】:How to save and read Facebook AccessToken in UserDefaults?如何在 UserDefaults 中保存和读取 Facebook AccessToken?
【发布时间】:2018-01-16 00:39:01
【问题描述】:

我使用 FirebaseAuthUi 在我的应用中管理身份验证。

当用户登录时,我需要他们的 Facebook 访问令牌来发出图形请求。用户第一次登录时它运行良好,但当应用程序重新启动时,图形 API 调用不起作用,因为我不再拥有 Facebook 访问令牌。

所以我需要将此令牌保存在 UserDefaults 或 Keychain 中。我的问题是我无法将此令牌保存为 AccessToken。我可以将它保存为字符串,但是当我想进行图形调用时,我需要一个 AccessToken,我认为我无法从保存的字符串中获取 AccessToken。

你知道我是怎么做到的吗?这是我的代码:

//checkLoggedIn
authHandle = Auth.auth().addStateDidChangeListener { auth, user in
    if let user = user {
        // User is signed in.

        UserDefaults.standard.set(String(describing: AccessToken.current), forKey: "savedFacebookToken")
        UserDefaults.standard.synchronize()
        let savedFacebookToken = UserDefaults.standard.object(forKey: "savedFacebookToken")

        let connection = GraphRequestConnection()
        connection.add(GraphRequest(graphPath: "/me/friends", accessToken: savedFacebookToken as! AccessToken)) { httpResponse, result in

我收到以下错误消息:

Could not cast value of type 'Swift._NSContiguousString' (0x10a0f4f50) to 'FacebookCore.AccessToken' (0x1068aa9f0).

编辑: 我还不能在真机上测试它。

【问题讨论】:

  • Alex 寻找答案,如果您有任何困惑,请告诉我。

标签: ios swift firebase facebook-graph-api firebase-authentication


【解决方案1】:

更好的方法-:

为 userDefaults- 创建扩展:

import  Foundation
// EXTENSION TO USER DEFAULTS
extension UserDefaults{

    // CREATE ENUM HAVING 1 STATE VALUE

    enum userDefaultKeys:String {
        case FacebookToken
       }

    // SAVE ACCESS TOKEN IN USER DEFAULTS

    func setAccessToken(id:String){
        set(id, forKey: userDefaultKeys.FacebookToken.rawValue)
        synchronize()
    }

// GET ACCESS TOKEN FROM USER DEFAULTS

    func getAccessToken()->String{

        return string(forKey: userDefaultKeys.FacebookToken.rawValue)
    }
}

在您的控制器类中,只需调用类似 -:

的方法

设置-:

// SET TOKEN AS STRING TO USER DEFAULTS

UserDefaults.standard.setAccessToken(value: "token") 

获取-:

// GET TOKEN RESULT AS STRING

    fileprivate func getSavedFacebookToken() -> String{
        return UserDefaults.standard.getAccessToken()
    }

根据您的代码-:

//checkLoggedIn
authHandle = Auth.auth().addStateDidChangeListener { auth, user in
    if let user = user {
        // User is signed in.

        UserDefaults.standard.setAccessToken(id: String(describing: AccessToken.current))
        let savedFacebookToken = UserDefaults.standard.getSavedFacebookToken()

         let connection = GraphRequestConnection()
        connection.add(GraphRequest(graphPath: "/me/friends", accessToken: AccessToken(savedFacebookToken))) { httpResponse, result in

REMRK-:

永远不要在 UserDefaults 中保存访问令牌。 NSUserDefaults 很容易 即使在非越狱设备上也可以阅读。如果安全是一个问题 你,那么我会将数据存储在 Keychain 中。

请参考以下链接-:

Storing authentication tokens on iOS - NSUserDefaults vs Keychain?

我会说无需保存令牌,它可能会过期或更改,这可能会在您的应用中产生问题。

阅读有关 Access Token 的 Facebook 文档以获得更多说明-:

https://developers.facebook.com/docs/facebook-login/access-tokens

【讨论】:

  • 谢谢,问题是如果我将令牌保存为字符串,我不知道如何进行图形 api 调用,因为它需要一个 AccessToken,而不是字符串。
  • @Alex9494 您可以将字符串更改为您想要的任何类型。而不是字符串使其成为int。你想要什么类型的 Int?尝试代码一次。
  • @Alex9494 我编辑过代码尝试一次让我知道令牌(int,string)的类型是什么?
  • 我无法构建应用程序,当它设置访问令牌时它说:无法转换类型“AccessToken?”的值到预期的参数类型“字符串”。而且我不想将我的令牌转换为字符串,因为那样我的图形 api 调用需要一个 AccessToken。 Facebook AccessToken 既不是字符串也不是 Int,它是 @Puneet Sharma 所说的结构
  • 请投反对票的原因?
【解决方案2】:

您的访问令牌是整数,它不是字符串类型转换。您可以按此保存值,也可以根据您的保存值使用最后一行代码。

 UserDefaults.standard.set(AccessToken.current, forKey: "savedFacebookToken")

获取代币价值

let currenttoken  = UserDefaults.standard.integer(forKey: "savedFacebookToken")

或者你可以转换成字符串

 let currenttoken=  UserDefaults.standard.object(forKey: "savedFacebookToken") as! String

【讨论】:

  • 我无法通过这种方式将我的 AccessToken 设置为 UserDefault,它显示:[用户默认值] 尝试设置非属性列表对象 FacebookCore.AccessToken。如果我将它保存为字符串,那么我无法在需要 AccessToken 而不是字符串的图形 api 调用中使用它...
  • 如果显示此错误是因为您在 userdefaulta 中添加了 nil 值对于非 nil 属性值,您可以将 NSKeyedArchiver.archivedData 保存在此格式中
【解决方案3】:

FacebookCore.AccessToken 是一个结构体,这意味着您不能将其直接保存到 UserDefaults 但您需要它来创建图形请求。

这意味着 SDK 必须在用户已经登录的情况下为您提供访问令牌值。AccessToken 类中有一个方法可以准确地为您提供该值

您只需要刷新当前的 Token 并延长 Token 的有效期。

AccessToken.refreshCurrentToken { accessToken, error in
    if let currentAccessToken = accessToken {
        let connection = GraphRequestConnection()
        connection.add(GraphRequest(graphPath: "/me/friends", accessToken: currentAccessToken)) {..}
    } else {
        // Show Login
    }
}

【讨论】:

  • 我的问题是,当用户登录时,SDK 并不总是为我提供 accessToken:如果用户登录 -> 关闭应用程序 -> 重新打开应用程序,用户仍然登录但访问令牌为空。这就是为什么我想在用户登录时保存它。我使用 FirebaseAuthUI 进行登录流程,我不是第一个遇到此问题的人(请参阅this for example)。我刚刚尝试了您的代码,这是我重新打开应用程序时调用的“else”部分,因为 accessToken 为 nil。
  • @Alex9494 :我以这种方式使用了 FBSDKCoreKit FBSDKAccessToken 并且它在设备上运行。在模拟器上,它不起作用。我希望您正在尝试使用实际设备。另外,Swift 版本的 SDK 还处于测试阶段,可能这就是它无法正常工作的原因。
  • 我目前只在模拟器上工作。几天后我就可以在设备上运行它,我会告诉你它是否有效。疯狂的是,当我第一次登录时它可以工作(= 我得到一个 accessToken,我可以调用我的图形 api),然后当我关闭并重新打开应用程序时,我不再有 accessToken。
  • @Alex9494:你必须在你的问题中提到它。旧的 Objective-C SDK 也无法使用模拟器。
  • @Alex9494:查看此链接stackoverflow.com/questions/39786577/…
猜你喜欢
  • 1970-01-01
  • 2011-05-19
  • 2012-11-06
  • 2019-03-30
  • 1970-01-01
  • 1970-01-01
  • 2018-07-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多