-
Notifications
You must be signed in to change notification settings - Fork 88
add auth page with code snippets #512
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
| using dotnet; | ||
| using MongoDB.Bson; | ||
|
|
@@ -84,8 +86,79 @@ public async System.Threading.Tasks.Task ModifiesATask() | |
| return; | ||
| } | ||
|
|
||
| [Test] | ||
| public async System.Threading.Tasks.Task LogsOnManyWays() | ||
| { | ||
| // :code-block-start: logon_anon | ||
| Realms.Sync.User anonUser = await app.LogInAsync(Credentials.Anonymous()); | ||
| // :code-block-end: | ||
| Assert.AreEqual(UserState.LoggedIn, anonUser.State); | ||
| await anonUser.LogOutAsync(); | ||
| // :code-block-start: logon_EP | ||
| Realms.Sync.User emailUser = await app.LogInAsync(Credentials.EmailPassword("caleb@mongodb.com", "shhhItsASektrit!")); | ||
| // :code-block-end: | ||
| Assert.AreEqual(UserState.LoggedIn, emailUser.State); | ||
| await emailUser.LogOutAsync(); | ||
| // :code-block-start: logon_API | ||
| Realms.Sync.User apiUser = await app.LogInAsync(Credentials.ApiKey("eRECwv1e6gkLEse99XokWOgegzoguEkwmvYvXk08zAucG4kXmZu7TTgV832SwFCv")); | ||
| // :code-block-end: | ||
| Assert.AreEqual(UserState.LoggedIn, apiUser.State); | ||
| await apiUser.LogOutAsync(); | ||
| // :code-block-start: logon_Function | ||
| var functionParameters = new Dictionary<string, string>() | ||
| { | ||
| { "username", "caleb" }, | ||
| { "password", "shhhItsASektrit!" }, | ||
| { "someOtherProperty", "cheesecake" } | ||
| }; | ||
| Realms.Sync.User functionUser = | ||
| await app.LogInAsync(Credentials.Function(functionParameters)); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will work, but the code can be simplified by using anonymous objects: var functionParameters = new
{
username = "caleb",
password = "shhhItsASektrit",
someOtherProperty = "cheesecake"
};
var functionUser = await app.LogInAsync(Credentials.Function(functionParameters));Note that when using the anonymous object syntax, you can also hint that properties don't have to be strings only. Any serializable .NET type, including embedded objects will work: var functionParameters = new
{
biometricsValidated = false,
todaysDate = DateTime.UtcNow
}Of course, don't have to go overboard with the extra properties, just FYI.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. niiiiice |
||
| // :code-block-end: | ||
| Assert.AreEqual(UserState.LoggedIn, functionUser.State); | ||
| await functionUser.LogOutAsync(); | ||
| // :code-block-start: logon_JWT | ||
| Realms.Sync.User jwtUser = | ||
| await app.LogInAsync(Credentials.JWT("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkNhbGViIiwiaWF0IjoxNjAxNjc4ODcyLCJleHAiOjI1MTYyMzkwMjIsImF1ZCI6InR1dHMtdGlqeWEifQ.LHbeSI2FDWrlUVOBxe-rasuFiW-etv2Gu5e3eAa6Y6k")); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it be better to call it <JWT_token> similar to the fb and google examples? And is this a real credential that should be removed prior to commit? |
||
| // :code-block-end: | ||
| Assert.AreEqual(UserState.LoggedIn, jwtUser.State); | ||
| await jwtUser.LogOutAsync(); | ||
| try | ||
| { | ||
| // :code-block-start: logon_fb | ||
| Realms.Sync.User fbUser = | ||
| await app.LogInAsync(Credentials.Facebook("<facebook_token>")); | ||
| // :code-block-end: | ||
| } | ||
| catch (Exception e) | ||
| { | ||
| Assert.AreEqual("http error code considered fatal: Client Error: 401", e.Message); | ||
| } | ||
| try | ||
| { | ||
| // :code-block-start: logon_google | ||
| Realms.Sync.User googleUser = | ||
| await app.LogInAsync(Credentials.Google("<google_token>")); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we're calling this google auth code now as using the access token flow doesn't work. |
||
| // :code-block-end: | ||
| } | ||
| catch (Exception e) | ||
| { | ||
| Assert.AreEqual("http error code considered fatal: Client Error: 401", e.Message); | ||
| } | ||
| try | ||
| { | ||
| // :code-block-start: logon_apple | ||
| Realms.Sync.User appleUser = | ||
| await app.LogInAsync(Credentials.Apple("<apple_token>")); | ||
| // :code-block-end: | ||
| } | ||
|
|
||
| catch (Exception e) | ||
| { | ||
| Assert.AreEqual("http error code considered fatal: Client Error: 401", e.Message); | ||
| } | ||
| } | ||
|
|
||
| [TearDown] | ||
| [TearDown] | ||
| public async System.Threading.Tasks.Task TearDown() | ||
| { | ||
| config = new SyncConfiguration("My Project", user); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,115 +15,150 @@ Authenticate a User | |
| Overview | ||
| -------- | ||
|
|
||
| .. _dotnet-login: | ||
| {+service+} provides an API for authenticating users using any enabled | ||
| authentication provider. Instantiate a ``Credentials`` object and pass | ||
| it to the ``app.login()`` method to authenticate a user and create a ``User`` | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The .NET method is "to authenticate a user and create a |
||
| object. Each authentication provider corresponds to a method used to | ||
| instantiate ``Credentials`` objects using that authentication provider. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This sounds a bit heavy - perhaps if we inverted the flow, it would be easier to follow. I.e. something like "The |
||
| See the table below to find the method that instantiates the | ||
| ``Credentials`` instance for your authentication provider: | ||
|
|
||
| .. list-table:: | ||
| :header-rows: 1 | ||
| :widths: 50 50 | ||
|
|
||
| * - Authentication Provider | ||
| - Credentials Generation Method | ||
|
|
||
| * - :ref:`Anonymous <dotnet-login-anonymous>` | ||
| - ``Credentials.Anonymous()`` | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would be nice if those linked to the API docs for that method as those typically contain valuable information about parameters, return types, etc. I can send you a .zip containing the API docs for the v10 SDK if that would help.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, please...or a link would be fine, too. |
||
|
|
||
| * - :ref:`Email/Password <dotnet-login-email-password>` | ||
| - ``Credentials.EmailPassword(email, password)`` | ||
|
|
||
| * - :ref:`API Key <dotnet-login-api-key>` | ||
| - ``Credentials.ApiKey(userAPIKey)`` | ||
|
|
||
| * - :ref:`Custom Function <dotnet-login-custom-function>` | ||
| - ``Credentials.Function(functionPayload)`` | ||
|
|
||
| * - :ref:`Custom JWT <dotnet-login-custom-jwt>` | ||
| - ``Credentials.JWT(jwt)`` | ||
|
|
||
| * - :ref:`Google OAuth <dotnet-login-google>` | ||
| - ``Credentials.Google(googleAuthCode)`` | ||
|
|
||
| * - :ref:`Facebook OAuth <dotnet-login-facebook>` | ||
| - ``Credentials.Facebook(facebookToken)`` | ||
|
|
||
| * - :ref:`Sign-in With Apple <dotnet-login-apple>` | ||
| - ``Credentials.Apple(appleToken)`` | ||
|
|
||
|
|
||
| Before you can authenticate a user, ensure you have: | ||
|
|
||
| - :ref:`Created a {+app+} <create-a-realm-app>` | ||
| - Enabled one or more :ref:`authentication providers <authentication-providers>` | ||
| - :ref:`Installed the .NET SDK <dotnet-install>` | ||
|
|
||
|
|
||
| Log In | ||
| ------ | ||
|
|
||
| .. _dotnet-login-anonymous: | ||
|
|
||
| Anonymous | ||
| ~~~~~~~~~ | ||
| Anonymous Authentication | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| .. tabs-realm-languages:: | ||
| .. tab:: | ||
| :tabid: c-sharp | ||
| .. code-block:: csharp | ||
| If you have enabled :ref:`Anonymous authentication <anonymous-authentication>` in the | ||
| {+ui+}, users can immediately log into your app without providing any identifying | ||
| information. The following code shows how to do this: | ||
|
|
||
| .. literalinclude:: /examples/generated/code/start/RealmTests.codeblock.logon_anon.cs | ||
| :language: csharp | ||
|
|
||
| .. _dotnet-login-email-password: | ||
|
|
||
| Email/Password | ||
| ~~~~~~~~~~~~~~ | ||
| Email/Password Authentication | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| .. tabs-realm-languages:: | ||
|
|
||
| .. tab:: | ||
| :tabid: c-sharp | ||
|
|
||
| .. code-block:: csharp | ||
| If you have enabled :ref:`Email/Password authentication <email-password-authentication>`, | ||
| you can log in using the following code: | ||
|
|
||
| .. literalinclude:: /examples/generated/code/start/RealmTests.codeblock.logon_EP.cs | ||
| :language: csharp | ||
|
|
||
| .. _dotnet-login-api-key: | ||
|
|
||
| API Key | ||
| ~~~~~~~ | ||
| If you have enabled :ref:`API Key authentication <api-key-authentication>`, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since you've added Authentication to Anonymous and Email/Password headers, should you also update the rest of the authn method headers? |
||
| you can log in using the following code: | ||
|
|
||
| .. tabs-realm-languages:: | ||
|
|
||
| .. tab:: | ||
| :tabid: c-sharp | ||
|
|
||
| .. code-block:: csharp | ||
| .. literalinclude:: /examples/generated/code/start/RealmTests.codeblock.logon_API.cs | ||
| :language: csharp | ||
|
|
||
| .. _dotnet-login-custom-function: | ||
|
|
||
| Custom Function | ||
| ~~~~~~~~~~~~~~~ | ||
| If you have enabled the | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nitpick: I think we prefer past tense over past perfect. E.g. "If you enabled ..." instead of "If you have enabled..." Applies to all instances. |
||
| :doc:`Custom Function authentication provider </authentication/custom-function>`, | ||
| you can log in using the following code: | ||
|
|
||
| .. tabs-realm-languages:: | ||
|
|
||
| .. tab:: | ||
| :tabid: c-sharp | ||
|
|
||
| .. code-block:: csharp | ||
| .. literalinclude:: /examples/generated/code/start/RealmTests.codeblock.logon_Function.cs | ||
| :language: csharp | ||
|
|
||
| .. _dotnet-login-custom-jwt: | ||
|
|
||
| Custom JWT | ||
| ~~~~~~~~~~ | ||
| If you have enabled the :doc:`Custom JWT authentication provider </authentication/custom-jwt>`, | ||
| you can log in using the following code: | ||
|
|
||
| .. tabs-realm-languages:: | ||
|
|
||
| .. tab:: | ||
| :tabid: c-sharp | ||
|
|
||
| .. code-block:: csharp | ||
| .. literalinclude:: /examples/generated/code/start/RealmTests.codeblock.logon_JWT.cs | ||
| :language: csharp | ||
|
|
||
| .. _dotnet-login-facebook: | ||
|
|
||
| Facebook OAuth | ||
| ~~~~~~~~~~~~~~ | ||
| Facebook Authentication | ||
| ~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| .. tabs-realm-languages:: | ||
|
|
||
| .. tab:: | ||
| :tabid: c-sharp | ||
|
|
||
| .. code-block:: csharp | ||
| If you have enabled :ref:`Facebook authentication <facebook-authentication>`, | ||
| you can log in using the following code: | ||
|
|
||
| .. literalinclude:: /examples/generated/code/start/RealmTests.codeblock.logon_fb.cs | ||
| :language: csharp | ||
|
|
||
| .. _dotnet-login-google: | ||
|
|
||
| Google OAuth | ||
| ~~~~~~~~~~~~ | ||
| Google Authentication | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| .. tabs-realm-languages:: | ||
|
|
||
| .. tab:: | ||
| :tabid: c-sharp | ||
|
|
||
| .. code-block:: csharp | ||
| If you have enabled :ref:`Google authentication <google-authentication>`, | ||
| you can log in using the following code: | ||
|
|
||
| .. literalinclude:: /examples/generated/code/start/RealmTests.codeblock.logon_google.cs | ||
| :language: csharp | ||
|
|
||
| .. _dotnet-login-apple: | ||
|
|
||
| Sign-in with Apple | ||
| ~~~~~~~~~~~~~~~~~~ | ||
| If you have enabled :ref:`Sign-in with Apple authentication <apple-id-authentication>`, | ||
| you can log in using the following code: | ||
|
|
||
| .. tabs-realm-languages:: | ||
|
|
||
| .. tab:: | ||
| :tabid: c-sharp | ||
|
|
||
| .. code-block:: csharp | ||
| .. literalinclude:: /examples/generated/code/start/RealmTests.codeblock.logon_apple.cs | ||
| :language: csharp | ||
|
|
||
| .. _dotnet-logout: | ||
|
|
||
| Log Out | ||
| ------- | ||
|
|
||
| .. tabs-realm-languages:: | ||
| .. tab:: | ||
| :tabid: c-sharp | ||
| .. code-block:: csharp | ||
| Once logged in, you can log out by calling the ``LogOutAsync()`` method: | ||
|
|
||
| .. literalinclude:: /examples/generated/code/start/RealmTests.codeblock.logout.cs | ||
| :language: csharp | ||
|
|
||
| .. include:: /includes/log-out-queries-in-progress.rst | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1 @@ | ||
| const string appId = "tuts-tijya"; | ||
| app = Realms.Sync.App.Create(appId); | ||
| app = Realms.Sync.App.Create(myRealmAppId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if that's the style of the docs, but I feel that using the fully qualified name is overly verbose and doesn't convey much useful information. It's also not very copy-pasteable as in my experience most projects use
vars for variables and a few use the type name (without the namespace).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nirinchev - the reason I had the FQDN here was because we have a user-defined class called "User", so the compiler complained. I've updated the custom class names because they are semi-arbitrary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My suggestion would be to always use
varas the variable name should be indicative enough. E.g.anonUseris obviously a User, so explicitly specifying the type is redundant. This also lets you avoid some of the type collisions.