// // UniWebViewAuthenticationSession.cs // Created by Wang Wei(@onevcat) on 2022-06-21. // // This file is a part of UniWebView Project (https://uniwebview.com) // By purchasing the asset, you are allowed to use this code in as many as projects // you want, only if you publish the final products under the name of the same account // used for the purchase. // // This asset and all corresponding files (such as source code) are provided on an // “as is” basis, without warranty of any kind, express of implied, including but not // limited to the warranties of merchantability, fitness for a particular purpose, and // noninfringement. In no event shall the authors or copyright holders be liable for any // claim, damages or other liability, whether in action of contract, tort or otherwise, // arising from, out of or in connection with the software or the use of other dealing in the software. // using UnityEngine; using System; /// /// Represents a session that can be used to authenticate a user through a web service. /// /// /// Initialize the session with a URL that points to the authentication webpage. A browser or a secure web view loads /// and displays the page. On completion, the service sends a callback URL to the session with an authentication token, /// and this triggers the `OnAuthenticationFinished` with the received URL. To make your app be invoked by the system, /// you need to also add the correct callback URL starting with the value of `CallbackScheme` to UniWebView's preferences. /// /// Usually this session processes an OAuth 2 flow. It will be used along with a following "exchange token" request, to /// finally get the user's access token to allow you use the service APIs on behalf of the user. This token exchange can /// happen in the client app, or you can pass the code to your server and let your server do the left work. /// /// UniWebView also provides built-in integrated authentication flows for several popular service. The the /// `UniWebViewAuthenticationFlow` cluster classes to use them and simplify your work. If the built-in models do not /// fit your work, you can use this class as a starting point of your own authentication integration. /// /// See https://docs.uniwebview.com/guide/oauth2.html for a more detailed guide of authentication in UniWebView. /// public class UniWebViewAuthenticationSession: UnityEngine.Object { /// /// Delegate for authentication session finished event. /// /// The session which raised this event. /// /// The received URL from service. It might contain a valid `code` from the service, or an error. /// public delegate void AuthenticationFinishedDelegate(UniWebViewAuthenticationSession session, string url); /// /// Raised when the session finishes authentication. /// /// This event will be invoked when the service provider calls the callback URL. regardless of the authentication code /// is retrieved or an error is returned in the callback URL. /// public event AuthenticationFinishedDelegate OnAuthenticationFinished; /// /// Delegate for authentication session error encounter event. /// /// The session which raised this event. /// The error code represents the error type. /// The error message describes the error in detail. public delegate void AuthErrorReceivedDelegate(UniWebViewAuthenticationSession session, int errorCode, string errorMessage); /// /// Raised when the session encounters an error. /// /// This event will be invoked when the authentication session cannot finishes with a URL callback. This usually /// happens when a network error or the user dismisses the authentication page from native UI. /// public event AuthErrorReceivedDelegate OnAuthenticationErrorReceived; private string id = Guid.NewGuid().ToString(); private UniWebViewNativeListener listener; /// /// The URL of the authentication webpage. This is the value you used to create this session. /// public string Url { get; private set; } /// /// The callback scheme of the authentication webpage. This is the value you used to create this session. The service /// is expected to use a URL with this scheme to return to your app. /// public string CallbackScheme { get; private set; } internal void InternalAuthenticationFinished(string url) { if (OnAuthenticationFinished != null) { OnAuthenticationFinished(this, url); } UniWebViewNativeListener.RemoveListener(listener.Name); Destroy(listener.gameObject); } internal void InternalAuthenticationErrorReceived(UniWebViewNativeResultPayload payload) { if (OnAuthenticationErrorReceived != null) { int errorCode = int.TryParse(payload.resultCode, out errorCode) ? errorCode : -1; OnAuthenticationErrorReceived(this, errorCode, payload.data); } UniWebViewNativeListener.RemoveListener(listener.Name); Destroy(listener.gameObject); } private UniWebViewAuthenticationSession() { var listenerObject = new GameObject("UniWebViewAuthSession-" + id); listener = listenerObject.AddComponent(); UniWebViewNativeListener.AddListener(listener); } /// /// Check whether the current device and system supports the authentication session. /// /// /// This property always returns `true` on iOS 11, macOS 10.15 and later. On Android, it depends on whether there /// is an Intent can handle the safe browsing request, which is use to display the authentication page. Usually /// it is provided by Chrome. If there is no Intent can open the URL in safe browsing mode, this property will /// return `false`. /// /// To use this API on Android when you set your Target SDK to Android 11 or later, you need to declare the correct /// intent query explicitly in your AndroidManifest.xml, to follow the Package Visibility /// (https://developer.android.com/about/versions/11/privacy/package-visibility): /// /// ```xml /// /// /// /// /// /// ``` /// /// /// Returns `true` if the safe browsing mode is supported and the page will be opened in safe browsing /// mode. Otherwise, `false`. /// public static bool IsAuthenticationSupported { get { return UniWebViewInterface.IsAuthenticationIsSupported(); } } /// /// Creates a new authentication session with a given authentication page URL and a callback scheme. /// /// /// The authentication page which is provided by the service. It should be a URL with some information like your app's /// client id and required scopes, etc. /// /// The URL scheme which the service will use to navigate back to your client app. /// public static UniWebViewAuthenticationSession Create(string url, string callbackScheme) { var session = new UniWebViewAuthenticationSession(); session.listener.session = session; session.Url = url; session.CallbackScheme = callbackScheme; UniWebViewInterface.AuthenticationInit(session.listener.Name, url, callbackScheme); return session; } /// /// Start the authentication session process. It will show up a secured web page and navigate users to the `Url`. /// public void Start() { UniWebViewInterface.AuthenticationStart(listener.Name); } /// /// Sets to use the private mode for the authentication. If running under private mode, the previous stored /// authentication information will not be used. /// /// On Apple's platform, this works from iOS 13 and macOS 10.15. On Android, this depends on the Chrome setting on the /// device. The users should enable the "incognito" and "third-party incognito" to allow to use this feature. /// /// Check them in Chrome app: /// chrome://flags/#cct-incognito /// chrome://flags/#cct-incognito-available-to-third-party /// /// /// Whether the session should run in private mode or not. public void SetPrivateMode(bool flag) { UniWebViewInterface.AuthenticationSetPrivateMode(listener.Name, flag); } }