No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

UniWebViewAuthenticationSession.cs 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. //
  2. // UniWebViewAuthenticationSession.cs
  3. // Created by Wang Wei(@onevcat) on 2022-06-21.
  4. //
  5. // This file is a part of UniWebView Project (https://uniwebview.com)
  6. // By purchasing the asset, you are allowed to use this code in as many as projects
  7. // you want, only if you publish the final products under the name of the same account
  8. // used for the purchase.
  9. //
  10. // This asset and all corresponding files (such as source code) are provided on an
  11. // “as is” basis, without warranty of any kind, express of implied, including but not
  12. // limited to the warranties of merchantability, fitness for a particular purpose, and
  13. // noninfringement. In no event shall the authors or copyright holders be liable for any
  14. // claim, damages or other liability, whether in action of contract, tort or otherwise,
  15. // arising from, out of or in connection with the software or the use of other dealing in the software.
  16. //
  17. using UnityEngine;
  18. using System;
  19. /// <summary>
  20. /// Represents a session that can be used to authenticate a user through a web service.
  21. /// </summary>
  22. /// <remarks>
  23. /// Initialize the session with a URL that points to the authentication webpage. A browser or a secure web view loads
  24. /// and displays the page. On completion, the service sends a callback URL to the session with an authentication token,
  25. /// and this triggers the `OnAuthenticationFinished` with the received URL. To make your app be invoked by the system,
  26. /// you need to also add the correct callback URL starting with the value of `CallbackScheme` to UniWebView's preferences.
  27. ///
  28. /// Usually this session processes an OAuth 2 flow. It will be used along with a following "exchange token" request, to
  29. /// finally get the user's access token to allow you use the service APIs on behalf of the user. This token exchange can
  30. /// happen in the client app, or you can pass the code to your server and let your server do the left work.
  31. ///
  32. /// UniWebView also provides built-in integrated authentication flows for several popular service. The the
  33. /// `UniWebViewAuthenticationFlow` cluster classes to use them and simplify your work. If the built-in models do not
  34. /// fit your work, you can use this class as a starting point of your own authentication integration.
  35. ///
  36. /// See https://docs.uniwebview.com/guide/oauth2.html for a more detailed guide of authentication in UniWebView.
  37. /// </remarks>
  38. public class UniWebViewAuthenticationSession: UnityEngine.Object {
  39. /// <summary>
  40. /// Delegate for authentication session finished event.
  41. /// </summary>
  42. /// <param name="session">The session which raised this event.</param>
  43. /// <param name="url">
  44. /// The received URL from service. It might contain a valid `code` from the service, or an error.
  45. /// </param>
  46. public delegate void AuthenticationFinishedDelegate(UniWebViewAuthenticationSession session, string url);
  47. /// <summary>
  48. /// Raised when the session finishes authentication.
  49. ///
  50. /// This event will be invoked when the service provider calls the callback URL. regardless of the authentication code
  51. /// is retrieved or an error is returned in the callback URL.
  52. /// </summary>
  53. public event AuthenticationFinishedDelegate OnAuthenticationFinished;
  54. /// <summary>
  55. /// Delegate for authentication session error encounter event.
  56. /// </summary>
  57. /// <param name="session">The session which raised this event.</param>
  58. /// <param name="errorCode">The error code represents the error type.</param>
  59. /// <param name="errorMessage">The error message describes the error in detail.</param>
  60. public delegate void AuthErrorReceivedDelegate(UniWebViewAuthenticationSession session, int errorCode, string errorMessage);
  61. /// <summary>
  62. /// Raised when the session encounters an error.
  63. ///
  64. /// This event will be invoked when the authentication session cannot finishes with a URL callback. This usually
  65. /// happens when a network error or the user dismisses the authentication page from native UI.
  66. /// </summary>
  67. public event AuthErrorReceivedDelegate OnAuthenticationErrorReceived;
  68. private string id = Guid.NewGuid().ToString();
  69. private UniWebViewNativeListener listener;
  70. /// <summary>
  71. /// The URL of the authentication webpage. This is the value you used to create this session.
  72. /// </summary>
  73. public string Url { get; private set; }
  74. /// <summary>
  75. /// The callback scheme of the authentication webpage. This is the value you used to create this session. The service
  76. /// is expected to use a URL with this scheme to return to your app.
  77. /// </summary>
  78. public string CallbackScheme { get; private set; }
  79. internal void InternalAuthenticationFinished(string url) {
  80. if (OnAuthenticationFinished != null) {
  81. OnAuthenticationFinished(this, url);
  82. }
  83. UniWebViewNativeListener.RemoveListener(listener.Name);
  84. Destroy(listener.gameObject);
  85. }
  86. internal void InternalAuthenticationErrorReceived(UniWebViewNativeResultPayload payload) {
  87. if (OnAuthenticationErrorReceived != null) {
  88. int errorCode = int.TryParse(payload.resultCode, out errorCode) ? errorCode : -1;
  89. OnAuthenticationErrorReceived(this, errorCode, payload.data);
  90. }
  91. UniWebViewNativeListener.RemoveListener(listener.Name);
  92. Destroy(listener.gameObject);
  93. }
  94. private UniWebViewAuthenticationSession() {
  95. var listenerObject = new GameObject("UniWebViewAuthSession-" + id);
  96. listener = listenerObject.AddComponent<UniWebViewNativeListener>();
  97. UniWebViewNativeListener.AddListener(listener);
  98. }
  99. /// <summary>
  100. /// Check whether the current device and system supports the authentication session.
  101. /// </summary>
  102. /// <remarks>
  103. /// This property always returns `true` on iOS 11, macOS 10.15 and later. On Android, it depends on whether there
  104. /// is an Intent can handle the safe browsing request, which is use to display the authentication page. Usually
  105. /// it is provided by Chrome. If there is no Intent can open the URL in safe browsing mode, this property will
  106. /// return `false`.
  107. ///
  108. /// To use this API on Android when you set your Target SDK to Android 11 or later, you need to declare the correct
  109. /// intent query explicitly in your AndroidManifest.xml, to follow the Package Visibility
  110. /// (https://developer.android.com/about/versions/11/privacy/package-visibility):
  111. ///
  112. /// ```xml
  113. /// <queries>
  114. /// <intent>
  115. /// <action android:name="android.support.customtabs.action.CustomTabsService" />
  116. /// </intent>
  117. /// </queries>
  118. /// ```
  119. /// </remarks>
  120. /// <returns>
  121. /// Returns `true` if the safe browsing mode is supported and the page will be opened in safe browsing
  122. /// mode. Otherwise, `false`.
  123. /// </returns>
  124. public static bool IsAuthenticationSupported {
  125. get {
  126. return UniWebViewInterface.IsAuthenticationIsSupported();
  127. }
  128. }
  129. /// <summary>
  130. /// Creates a new authentication session with a given authentication page URL and a callback scheme.
  131. /// </summary>
  132. /// <param name="url">
  133. /// The authentication page which is provided by the service. It should be a URL with some information like your app's
  134. /// client id and required scopes, etc.
  135. /// </param>
  136. /// <param name="callbackScheme">The URL scheme which the service will use to navigate back to your client app.</param>
  137. /// <returns></returns>
  138. public static UniWebViewAuthenticationSession Create(string url, string callbackScheme) {
  139. var session = new UniWebViewAuthenticationSession();
  140. session.listener.session = session;
  141. session.Url = url;
  142. session.CallbackScheme = callbackScheme;
  143. UniWebViewInterface.AuthenticationInit(session.listener.Name, url, callbackScheme);
  144. return session;
  145. }
  146. /// <summary>
  147. /// Start the authentication session process. It will show up a secured web page and navigate users to the `Url`.
  148. /// </summary>
  149. public void Start() {
  150. UniWebViewInterface.AuthenticationStart(listener.Name);
  151. }
  152. /// <summary>
  153. /// Sets to use the private mode for the authentication. If running under private mode, the previous stored
  154. /// authentication information will not be used.
  155. /// <remarks>
  156. /// On Apple's platform, this works from iOS 13 and macOS 10.15. On Android, this depends on the Chrome setting on the
  157. /// device. The users should enable the "incognito" and "third-party incognito" to allow to use this feature.
  158. ///
  159. /// Check them in Chrome app:
  160. /// chrome://flags/#cct-incognito
  161. /// chrome://flags/#cct-incognito-available-to-third-party
  162. /// </remarks>
  163. /// </summary>
  164. /// <param name="flag">Whether the session should run in private mode or not.</param>
  165. public void SetPrivateMode(bool flag) {
  166. UniWebViewInterface.AuthenticationSetPrivateMode(listener.Name, flag);
  167. }
  168. }