Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(console): optimize api resource guides #6162

Merged
merged 1 commit into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 6 additions & 9 deletions packages/console/src/assets/docs/guides/api-python/README.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ import { appendPath } from '@silverhand/essentials';

<Step title="Extract the Bearer Token from request header">

```python
"""requires-auth.py
"""
```python title="requires-auth.py"
def get_auth_token():
auth = request.headers.get("Authorization", None)

Expand Down Expand Up @@ -42,7 +40,7 @@ pip install python-jose[ecdsa]
### Retrieve Logto's OIDC configurations

You will need a JWK public key set and the token issuer to verify the signature and source of the received JWS token.
All the latest public Logto Authorization Configurations can be found at <Code>{appendPath(props.endpoint, '/oidc/.well-known/openid-configuration')}</Code>.
All the latest public Logto Authorization Configurations can be found at <code>{appendPath(props.endpoint, '/oidc/.well-known/openid-configuration').href}</code>.

e.g. You can locate the following two fields in the response body if you request the above endpoint.

Expand All @@ -55,11 +53,8 @@ e.g. You can locate the following two fields in the response body if you request

### Create the authorization validation decorator

<Code className="language-python">
{`"""requires-auth.py
"""

import json
<Code className="language-python" title="requires-auth.py">
{`import json
from flask import request, _request_ctx_stack
from six.moves.urllib.request import urlopen
from functools import wraps
Expand Down Expand Up @@ -102,6 +97,8 @@ def requires_auth(f):
return decorated`}
</Code>

<br/>

<InlineNotification>
For <a href="https://docs.logto.io/docs/recipes/rbac/" target="_blank" rel="noopener">🔐 RBAC</a>, scope validation is also required.
</InlineNotification>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ and signed with [JWK](https://datatracker.ietf.org/doc/html/rfc7517)
Before moving on, you will need to get an issuer and a JWKS URI to verify the issuer and the signature of the Bearer Token (`access_token`).

All the Logto Authorization server configurations can be found by requesting{' '}
<Code>{appendPath(props.endpoint, '/oidc/.well-known/openid-configuration')}</Code>, including the{' '}
<code>{appendPath(props.endpoint, '/oidc/.well-known/openid-configuration').href}</code>, including the{' '}
<strong>issuer</strong>, <strong>jwks_uri</strong> and other authorization configs.

An example of the response:
Expand All @@ -72,9 +72,8 @@ An example of the response:

Use an `application.yml` file (instead of the default `application.properties`) to configure the server port, audience, and OAuth2 resource server.

<Code className="language-yaml">
{`# path/to/project/src/main/resources/application.yaml
server:
<Code className="language-yaml" title="resources/application.yaml">
{`server:
port: 3000

logto:
Expand All @@ -99,8 +98,7 @@ spring:

Provide your own `AudienceValidator` class that implements the `OAuth2TokenValidator` interface to validate whether the required audience is present in the JWT.

```java
// path/to/project/src/main/java/io/logto/springboot/sample/validator/AudienceValidator.java
```java title="validator/AudienceValidator.java"
package io.logto.springboot.sample.validator;

import org.springframework.security.oauth2.core.OAuth2Error;
Expand Down Expand Up @@ -142,8 +140,7 @@ Spring Security makes it easy to configure your application as a resource server

You need to provide instances of `JwtDecoder` and `SecurityFilterChain` (as Spring beans), and add the `@EnableWebSecurity` annotation.

```java
// path/to/project/src/main/java/io/logto/springboot/sample/configuration/SecurityConfiguration.java
```java title="configuration/SecurityConfiguration.java"
package io.logto.springboot.sample.configuration;

import com.nimbusds.jose.JOSEObjectType;
Expand Down Expand Up @@ -218,8 +215,7 @@ public class SecurityConfiguration {

Add a controller to provide the protected and public APIs:

```java
// path/to/project/src/main/java/io/logto/springboot/sample/controller/ProtectedController.java
```java title="controller/ProtectedController.java"
package io.logto.springboot.sample.controller;

import org.springframework.web.bind.annotation.CrossOrigin;
Expand Down Expand Up @@ -295,7 +291,7 @@ WWW-Authenticate: Bearer error="invalid_token", error_description="An error occu

</Step>

<Step title="Further readings">
<Step title="Resources">

- [Protect your API](https://docs.logto.io/docs/recipes/protect-your-api/)
- [Spring Security OAuth 2.0 Resource Server](https://docs.spring.io/spring-security/reference/servlet/oauth2/resource-server/index.html)
Expand Down
13 changes: 5 additions & 8 deletions packages/console/src/components/Guide/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ export const GuideContext = createContext<GuideContextType>({
function Guide({ className, guideId, isEmpty, isLoading, onClose }: Props) {
const guide = guides.find(({ id }) => id === guideId);
const GuideComponent = guide?.Component;
const isApiResourceGuide = guide?.metadata.target === 'API';
const context = useContext(GuideContext);

return (
Expand All @@ -69,13 +68,11 @@ function Guide({ className, guideId, isEmpty, isLoading, onClose }: Props) {
</Suspense>
</MdxProvider>
</OverlayScrollbar>
{!isApiResourceGuide && (
<nav className={styles.actionBar}>
<div className={styles.layout}>
<Button size="large" title="guide.finish_and_done" type="primary" onClick={onClose} />
</div>
</nav>
)}
<nav className={styles.actionBar}>
<div className={styles.layout}>
<Button size="large" title="guide.finish_and_done" type="primary" onClick={onClose} />
</div>
</nav>
</>
);
}
Expand Down
Loading