在 iOS 上使用 AppAuth 库刷新身份验证令牌

Posted

技术标签:

【中文标题】在 iOS 上使用 AppAuth 库刷新身份验证令牌【英文标题】:Refreshing auth token with AppAuth library on iOS 【发布时间】:2021-03-05 17:10:23 【问题描述】:

我正在使用 AppAuth library 获取 Gmail API 的访问令牌。我已经成功地创建了一个身份验证会话,并使用检索到的令牌稍后获取电子邮件。

在我的AppDelegate 中有两个变量:

var currentAuthorizationFlow: OIDExternalUserAgentSession?
var authState: OIDAuthState?

在我的SignInViewController 中,我有以下代码用于执行授权流程:

@objc func startAuthFlow() 
    
    Analytics.logEvent("auth_started", parameters: nil)
    
    let authorizationEndpoint = URL(string: "https://accounts.google.com/o/oauth2/v2/auth")!
    let tokenEndpoint = URL(string: "https://www.googleapis.com/oauth2/v4/token")!
    let configuration = OIDServiceConfiguration(authorizationEndpoint: authorizationEndpoint,
                                                tokenEndpoint: tokenEndpoint)
    let kRedirectURI: String = "com.googleusercontent.apps.someNumber:/oauthredirect";
    
    guard let redirectURI = URL(string: kRedirectURI) else 
        return
    
    
    let appDelegate = UIApplication.shared.delegate as! AppDelegate

    // builds authentication request
    let request = OIDAuthorizationRequest(configuration: configuration,
                                          clientId: "myID",
                                          clientSecret: nil,
                                          scopes: ["https://mail.google.com/"],
                                          redirectURL: redirectURI,
                                          responseType: OIDResponseTypeCode,
                                          additionalParameters: nil)
    

    
    // performs authentication request
    print("Initiating authorization request with scope: \(request.scope ?? "nil")")
            
    appDelegate.currentAuthorizationFlow =
        OIDAuthState.authState(byPresenting: request, presenting: self)  authState, error in
                if let authState = authState 

                print("Got authorization tokens. Access token: " +
                        "\(authState.lastTokenResponse?.accessToken ?? "nil")")
               A0SimpleKeychain().setString((authState.lastTokenResponse?.accessToken)!, forKey: "auth0-user-jwt")
                A0SimpleKeychain().setString((authState.lastTokenResponse?.refreshToken)!, forKey: "auth0-user-jwt-refresh")

                EmailFetcher.shared.setupEmailSession(token: (authState.lastTokenResponse?.accessToken)!)
                

             else 
              
                print("Authorization error: \(error?.localizedDescription ?? "Unknown error")")
            
        

然后我成功保存了令牌和刷新令牌。

我看到OIDAuthState 有一个tokenRefreshRequest() 方法,但我的理解是您需要传入刷新令牌才能获得一个新的、新鲜的令牌,对吗?使用 AppAuth 实现这一点缺少什么?

【问题讨论】:

【参考方案1】:

要刷新访问令牌,您可以使用带有类似以下参数的“刷新令牌授予”消息:

let request = OIDTokenRequest(
    configuration: self.metadata!,
    grantType: OIDGrantTypeRefreshToken,
    authorizationCode: nil,
    redirectURL: nil,
    clientID: self.configuration.clientId,
    clientSecret: nil,
    scope: nil,
    refreshToken: tokenData!.refreshToken!,
    codeVerifier: nil,
    additionalParameters: nil)

OIDAuthorizationService.perform(request)  tokenResponse, error in ...

请注意,我没有在示例中使用 AuthState 类,因为我想将加密的令牌存储在 ios 钥匙串中,因此您的代码可能会有所不同。对于要比较的东西,您可以运行博客中的代码示例:

Code Sample Blog Post

【讨论】:

【参考方案2】:

从身份验证令牌创建一个身份验证状态或直接将身份验证模型保存到密钥链中,然后使用以下方法访问最新的刷新令牌。 身份验证状态

authState.performAction  (accessToken, authToken, error) in
        guard let err = error else return 
        print("updated refresh token is : \(accessToken)")
     

【讨论】:

以上是关于在 iOS 上使用 AppAuth 库刷新身份验证令牌的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 上通过 Spotify App Remote 的 SPTSession 进行身份验证时获取一个奇怪的刷新令牌

WSO2 OAuth2:如何使用 AppAuth iOS 注销

在 asp.net vnext 上使用不记名令牌身份验证刷新令牌

如何在刷新页面上存储在本地存储中的 reactjs 中使用 JWT 进行身份验证?

使用 JWT 和刷新令牌对移动应用程序进行身份验证

如何使用 Firebase 刷新令牌保持用户身份验证?