iOS: redirect after a failed authorize() crashes the app (finished session kept as _currentSession)

Đã đóng
#1,151 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

@federicobartoli đang làm issue này rồi.

Từ ngày 9/10/2026.

  • #1152 của @federicobartoli — đang mở

Đánh giá

Độ khó
3/5
Thời gian dự kiến
Nửa ngày
Mức phù hợp với người mới
35/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
ios, objective-c, react-native, swift
Lĩnh vực
authentication, mobile

Hướng nghiên cứu

Start in packages/react-native-app-auth/ios/RNAppAuth.m: read authorizeWithConfiguration: where _currentSession is assigned, the completion block that clears it, and resumeExternalUserAgentFlowWithURL: near the top of the file. The author has already announced a fix and PR, so check for an open PR before starting. Done means a redirect that arrives after a failed authorize() no longer reaches a finished AppAuth session. This needs an iOS simulator with Xcode to verify.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Issue

When authorize() or logout() fails synchronously on iOS (the browser could not be opened), the native module keeps the failed AppAuth session as _currentSession. Any URL that later matches the redirect URL is forwarded to that finished session. With AppAuth 2.0.0 this terminates the app with an uncaught Objective-C exception:

An OAuth redirect was sent to a OIDExternalUserAgentSession after it already completed.

-[OIDAuthorizationSession resumeExternalUserAgentFlowWithURL:]  (OIDAuthorizationService.m:135)
-[RNAppAuth resumeExternalUserAgentFlowWithURL:]                (RNAppAuth.m:20)
AppDelegate.application(_:open:options:)                        (AppDelegate.swift:51)

It is an NSException, so a Swift AppDelegate cannot catch it.

This is the same exception and stack as #1080, with a different trigger. I have not reproduced the #1080 trigger myself.

Reproduction with examples/demo on the simulator

main at 93d06bc, AppAuth 2.0.0 as pinned by examples/demo/ios/Podfile.lock, Xcode 26.3, iPhone 17 Pro simulator on iOS 26.1.

  1. In examples/demo/App.tsx, add iosCustomBrowser: 'chrome' to the options passed to authorize().
  2. In examples/demo/ios/Example/Info.plist, add googlechromes to LSApplicationQueriesSchemes (AppAuth asserts on this in debug builds).
  3. Run the app on a simulator, where Chrome is not installed, and tap Login with IdentityServer. An alert appears: "Failed to log in", Unable to open Safari.
  4. Dismiss the alert, then deliver a URL that matches the redirect URL:
   xcrun simctl openurl booted "io.identityserver.demo:/oauthredirect?code=x&state=y"
  1. The app crashes with the stack above.

code and state are dummy values on purpose: the app crashes before either of them is read.

How I hit it in a production app

authorize() with iosCustomBrowser: 'safari', on an iPhone where Safari is disabled (Settings > Screen Time > Content & Privacy Restrictions > Allowed Apps) and Chrome is the default browser:

  1. Chrome opens with the login page, but the promise has already been rejected with Unable to open Safari.
  2. The user logs in and Chrome redirects to the app's custom scheme.
  3. The app is terminated with the exception above.

With Safari enabled the same flow works. Why AppAuth reports a failure although a browser did open is a separate problem in AppAuth's custom browser user-agent, which I will report to openid/AppAuth-iOS. Here it is only the trigger.

Cause

Links are to main at 93d06bc and to AppAuth 2.0.0.

  1. authorizeWithConfiguration: stores the session returned by AppAuth (RNAppAuth.m#L441-L443).
  2. AppAuth presents the session before returning it. If presenting fails, it completes the session and invokes the callback synchronously, before that call returns (OIDAuthorizationService.m#L74-L86, through OIDAuthState.m#L167-L169).
  3. The callback clears _currentSession (RNAppAuth.m#L426-L427). Then the call from step 1 returns, and the assignment puts the finished session back.
  4. From then on, every URL that reaches the app delegate is forwarded to that session (RNAppAuth.m#L19-L21). AppAuth accepts the URL if scheme, host and path match the redirect URL (the query is ignored), finds no pending callback and raises (OIDAuthorizationService.m#L123-L135).

The other authorize branches and logout follow the same pattern.

There is a second way to reach the same exception, which I found by reading the code and have not reproduced: _currentSession stays set until the code exchange finishes, while the AppAuth session is already complete once it has consumed the redirect. A second matching URL that arrives during the token request is forwarded to a finished session too.

AppAuth versions

AppAuth 2.1.0 replaced the exception with a NO return value (openid/AppAuth-iOS#955), so the crash needs AppAuth < 2.1.0. The podspec accepts AppAuth >= 1.7.6, and a project that already has 2.0.0 in its Podfile.lock keeps it until pod update. Holding on to a finished session looks wrong on any version, so I think it is worth fixing here as well.

I have a fix ready and will open a PR right after this issue.


Environment

  • Your Identity Provider: Keycloak (production app); the Duende demo server configured in examples/demo (simulator reproduction)
  • Platform that you're experiencing the issue on: iOS
  • Your react-native Version: 0.82.1 (production app, new architecture, Swift AppDelegate); 0.79.2 (examples/demo)
  • Your react-native-app-auth Version: 8.4.1 (production app); main at 93d06bc, i.e. 8.5.0 (examples/demo)
  • Are you using Expo? No
  • AppAuth pod: 2.0.0 in both
  • Device (production app): Apple iPhone 15 iOS: 27.0
Ngôn ngữ chính
Java
Star
2.3k
Fork
471
Merge trung bình
4 ngày 3 giờ
Pull request đã merge (30 ngày)
7

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của FormidableLabs/react-native-app-auth

Tất cả issue của FormidableLabs/react-native-app-auth

Issue tương tự

Thêm issue về Java

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.