Skip to content

Commit

Permalink
Merge pull request #6177 from logto-io/gao-update-dotnet-guides
Browse files Browse the repository at this point in the history
refactor(console): improve dotnet guides
  • Loading branch information
gao-sun authored Jul 5, 2024
2 parents d85cd32 + 0453f80 commit 1efa7e7
Show file tree
Hide file tree
Showing 21 changed files with 250 additions and 410 deletions.
2 changes: 2 additions & 0 deletions packages/console/parcel-transformer-mdx2.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { compile } from '@mdx-js/mdx';
import { default as ThrowableDiagnostic } from '@parcel/diagnostic';
import { Transformer } from '@parcel/plugin';
import rehypeMdxCodeProps from 'rehype-mdx-code-props';
import remarkGfm from 'remark-gfm';

export default new Transformer({
async transform({ asset }) {
Expand All @@ -16,6 +17,7 @@ export default new Transformer({
development: true,
jsx: true,
providerImportSource: '@mdx-js/react',
remarkPlugins: [remarkGfm],
rehypePlugins: [[rehypeMdxCodeProps, { tagName: 'code' }]],
});
} catch (error) {
Expand Down
20 changes: 0 additions & 20 deletions packages/console/src/assets/docs/fragments/_experience-overview.md

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import RegardingRedirectBasedSignIn from './_regarding-redirect-based-sign-in.md';

Before we dive into the details, here's a quick overview of the end-user experience. The sign-in process can be simplified as follows:

```mermaid
graph LR
A(Your app) -->|1. Invoke sign-in| B(Logto)
B -->|2. Finish sign-in| A
```

1. Your app invokes the sign-in method.
2. The user is redirected to the Logto sign-in page. For native apps, the system browser is opened.
3. The user signs in and is redirected back to your app (configured as the redirect URI).

<RegardingRedirectBasedSignIn />

---
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import InlineNotification from '@/ds-components/InlineNotification';
import UriInputField from '@/mdx-components/UriInputField';

import ExperienceOverview from './_experience-overview.md';
import ExperienceOverview from './_experience-overview.mdx';

export const defaultRedirectUri = 'io.logto://callback';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import InlineNotification from '@/ds-components/InlineNotification';
import UriInputField from '@/mdx-components/UriInputField';

import ExperienceOverview from './_experience-overview.md';
import ExperienceOverview from './_experience-overview.mdx';

export const defaultBaseUrl = 'http://localhost:3000/';
export const defaultRedirectUri = `${defaultBaseUrl}callback`;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Details>
<summary>Regarding redirect-based sign-in</summary>

1. This authentication process follows the [OpenID Connect (OIDC)](https://openid.net/specs/openid-connect-core-1_0.html) protocol, and Logto enforces strict security measures to protect user sign-in.
2. If you have multiple apps, you can use the same identity provider (Logto). Once the user signs in to one app, Logto will automatically complete the sign-in process when the user accesses another app.

To learn more about the rationale and benefits of redirect-based sign-in, see [Logto sign-in experience explained](../../docs/tutorials/get-started/sign-in-experience.mdx).

</Details>
Original file line number Diff line number Diff line change
@@ -1,50 +1,35 @@
import UriInputField from '@/mdx-components/UriInputField';
import Steps from '@/mdx-components/Steps';
import Step from '@/mdx-components/Step';
import SignInAndSignOutFlows from '../web-dotnet-core-mvc/fragments/_sign-in-and-sign-out-flows.mdx';
import ConfigureRedirectUris from '../web-dotnet-core-mvc/fragments/_configure-redirect-uris.mdx';
import Installation from '../web-dotnet-core-mvc/fragments/_installation.md';
import AddAuthentication from '../web-dotnet-core-mvc/fragments/_add-authentication.mdx';
import DisplayUserInformation from '../web-dotnet-core-mvc/fragments/_display-user-information.md';
import Checkpoint from '../../fragments/_checkpoint.md';

<Steps>

<Step title="Get started">
<Step title="Add Logto SDK as a dependency">

This tutorial will show you how to use Logto ASP.NET Core authentication middleware to protect your web application.

<ul>
<li>It assumes your website is hosted on <code>{props.sampleUrls.origin}</code>.</li>
</ul>

### Installation

```bash
dotnet add package Logto.AspNetCore.Authentication
```
<Installation />

</Step>

<Step title="Add Logto authentication">

Open `Startup.cs` (or `Program.cs`) and add the following code to register Logto authentication middleware:
<AddAuthentication {...props} />

<Code className="language-csharp">
{`using Logto.AspNetCore.Authentication;
</Step>

var builder = WebApplication.CreateBuilder(args);
<Step title="Understand sign-in and sign-out flows">

builder.Services.AddLogtoAuthentication(options =>
{
options.Endpoint = "${props.endpoint}";
options.AppId = "${props.app.id}";
options.AppSecret = "${props.app.secret}";
});
<SignInAndSignOutFlows />

app.UseAuthentication();`}
</Code>
</Step>

The `AddLogtoAuthentication` method will do the following things:
<Step title="Configure redirect URIs">

- Set the default authentication scheme to `LogtoDefaults.CookieScheme`.
- Set the default challenge scheme to `LogtoDefaults.AuthenticationScheme`.
- Set the default sign-out scheme to `LogtoDefaults.AuthenticationScheme`.
- Add cookie and OpenID Connect authentication handlers to the authentication scheme.
<ConfigureRedirectUris />

</Step>

Expand All @@ -54,7 +39,7 @@ Since Blazor Server uses SignalR to communicate between the server and the clien

To make it right, we need to explicitly add two endpoints for sign-in and sign-out redirects:

```csharp
```csharp title="Program.cs"
app.MapGet("/SignIn", async context =>
{
if (!(context.User?.Identity?.IsAuthenticated ?? false))
Expand All @@ -80,35 +65,11 @@ Now we can redirect to these endpoints to trigger sign-in and sign-out.

</Step>

<Step title="Set up redirect URIs">

<p>
First, let's enter your redirect URI. E.g. <code>{props.sampleUrls.origin + 'Callback'}</code> (replace the endpoint with yours). This is where Logto will redirect users after they sign in.
</p>

<UriInputField name="redirectUris" />

Remember to keep the path `/Callback` in the URI as it's the default value for the Logto authentication middleware.

---

To clean up both ASP.NET session and Logto session, we can designate a post sign-out redierct URI. This is where Logto will redirect users after they sign out.

<p>
For example, set the URI to <code>{props.sampleUrls.origin + 'SignedOutCallback'}</code> (replace the endpoint with yours):
</p>

<UriInputField name="postLogoutRedirectUris" />

Remember to keep the path `/SignedOutCallback` in the URI as it's the default value for the Logto authentication middleware.

</Step>

<Step title="Sign-in and sign-out">

In the Razor component, add the following code:

```cshtml
```cshtml title="Components/Pages/Index.razor"
@using Microsoft.AspNetCore.Components.Authorization
@using System.Security.Claims
@inject AuthenticationStateProvider AuthenticationStateProvider
Expand Down Expand Up @@ -158,41 +119,13 @@ The page will show the "Sign in" button if the user is not authenticated, and sh

</Step>

<Step title="Checkpoint: Test your application">

Now you can run the web application and try to sign in and sign out with Logto:

1. Open the web application in your browser, you should see "Is authenticated: False" and the "Sign in" button.
2. Click the "Sign in" button, and you should be redirected to the Logto sign-in page.
3. After you have signed in, you should be redirected back to the web application, and you should see "Is authenticated: True" and the "Sign out" button.
4. Click the "Sign out" button, and you should be redirected to the Logto sign-out page, and then redirected back to the web application.

</Step>

<Step title="The user object">

To know if the user is authenticated, you can check the `User.Identity?.IsAuthenticated` property.

To get the user profile claims, you can use the `User.Claims` property:

```csharp
var claims = User.Claims;

// Get the user ID
var userId = claims.FirstOrDefault(c => c.Type == LogtoParameters.Claims.Subject)?.Value;
```

See the [full tutorial](https://docs.logto.io/quick-starts/dotnet-core/blazor-server/) for more details.

</Step>

<Step title="The `<AuthorizeView />` component">
<Step title="Alternative: Use the `AuthorizeView` component">

Alternatively, you can use the `AuthorizeView` component to conditionally render content based on the user's authentication state. This component is useful when you want to show different content to authenticated and unauthenticated users.

In your Razor component, add the following code:

```cshtml
```cshtml title="Components/Pages/Index.razor"
@using Microsoft.AspNetCore.Components.Authorization
@* ... *@
Expand All @@ -212,12 +145,24 @@ In your Razor component, add the following code:

The `AuthorizeView` component requires a cascading parameter of type `Task<AuthenticationState>`. A direct way to get this parameter is to add the `<CascadingAuthenticationState>` component. However, due to the nature of Blazor Server, we cannot simply add the component to the layout or the root component (it may not work as expected). Instead, we can add the following code to the builder (`Program.cs` or `Startup.cs`) to provide the cascading parameter:

```csharp
```csharp title="Program.cs"
builder.Services.AddCascadingAuthenticationState();
```

Then you can use the `AuthorizeView` component in every component that needs it.

</Step>

<Step title="Checkpoint: Test your application">

<Checkpoint />

</Step>

<Step title="Display user information">

<DisplayUserInformation />

</Step>

</Steps>
Loading

0 comments on commit 1efa7e7

Please sign in to comment.