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.

UniWebViewAuthenticationCommonFlow.cs 4.5KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. //
  2. // UniWebViewAuthenticationCommonFlow.cs
  3. // Created by Wang Wei (@onevcat) on 2022-06-25.
  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 System.Collections.Generic;
  18. using UnityEngine;
  19. /// <summary>
  20. /// Abstract class and general control for other authentication flows. This class determines the global behaviors of the
  21. /// authentication flow, such as whether to start authentication as soon as the script `Start`s, and whether to use private
  22. /// mode to authenticate the user.
  23. /// This is a super and abstract class for all concrete auth flow. You are not expected to use this class directly.
  24. /// Instead, to start a customized auth flow, you can use the `UniWebViewAuthenticationFlowCustomize` class.
  25. /// </summary>
  26. public abstract class UniWebViewAuthenticationCommonFlow: MonoBehaviour {
  27. /// <summary>
  28. /// Whether to start authentication as soon as the script `Start`s.
  29. /// </summary>
  30. public bool authorizeOnStart;
  31. /// <summary>
  32. /// Whether to use private mode to authenticate the user. If `true` and the device supports, the authentication
  33. /// will begin under the incognito mode.
  34. ///
  35. /// On iOS, this works on iOS 13 and later.
  36. ///
  37. /// On Android, it depends on the Chrome version and might require users to enable the incognito mode (and support
  38. /// for third-party use) in Chrome's settings. Check settings with `chrome://flags/#cct-incognito` and
  39. /// `chrome://flags/#cct-incognito-available-to-third-party` in Chrome to see the current status.
  40. /// </summary>
  41. public bool privateMode;
  42. // Security. Store the state.
  43. private string state;
  44. // Security. Store the code challenge verifier.
  45. private string codeVerify;
  46. protected string CodeVerify => codeVerify;
  47. public void Start() {
  48. if (authorizeOnStart) {
  49. StartAuthenticationFlow();
  50. }
  51. }
  52. /// <summary>
  53. /// Subclass should override this method to start the authentication flow. Usually it starts
  54. /// a `UniWebViewAuthenticationFlow`. But you can also choose whatever you need to do.
  55. /// </summary>
  56. public abstract void StartAuthenticationFlow();
  57. /// <summary>
  58. /// Subclass should override this method to start the authentication flow. Usually it starts
  59. /// a Unity Web Request against the authentication flow's token entry point to refresh the token.
  60. /// </summary>
  61. /// <param name="refreshToken">The refresh token.</param>
  62. public abstract void StartRefreshTokenFlow(string refreshToken);
  63. // Child classes are expected to call this method to request a `state` (and store it for later check) if the
  64. // `state` verification is enabled.
  65. protected string GenerateAndStoreState() {
  66. state = UniWebViewAuthenticationUtils.GenerateRandomBase64URLString();
  67. return state;
  68. }
  69. // Child classes are expected to call this method to request a `code_challenge`. Later when exchanging the access
  70. // token, the `code_verifier` will be used to verify the `code_challenge`. Subclass can read it from `CodeVerify`.
  71. protected string GenerateCodeChallengeAndStoreCodeVerify(UniWebViewAuthenticationPKCE method) {
  72. codeVerify = UniWebViewAuthenticationUtils.GenerateCodeVerifier();
  73. return UniWebViewAuthenticationUtils.CalculateCodeChallenge(codeVerify, method);
  74. }
  75. // Perform verifying for `state`.
  76. protected void VerifyState(Dictionary<string, string> parameters, string key = "state") {
  77. if (state == null) {
  78. throw AuthenticationResponseException.InvalidState;
  79. }
  80. if (!parameters.TryGetValue(key, out var stateInResponse) || state != stateInResponse) {
  81. throw AuthenticationResponseException.InvalidState;
  82. }
  83. }
  84. }