{{ idTokenClaims | json }}
- Access token: {{ accessToken }}
- - -{{ claims | json }}
+}
```
### Request additional claims \{#request-additional-claims}
-{{ error.message }}
+ } @else { +Completing sign-in...
+ } + `, +}) +export class CallbackComponent { + readonly logto = inject(LogtoService); + + constructor() { + afterNextRender(() => { + void (async () => { + const callbackUri = window.location.href; + + if (!(await this.logto.isSignInRedirected(callbackUri))) { + window.location.replace(window.location.origin); + return; + } + + await this.logto.handleSignInCallback(callbackUri); + })().catch(() => { + // The SDK exposes callback errors through logto.error() for the template. + }); + }); + } +} +``` -```ts title="app/app.config.ts" -export const appConfig: ApplicationConfig = { - providers: [ - provideAuth({ - config: buildAngularAuthConfig({ - // ...other config - // highlight-start - redirectUri: 'http://localhost:3000/callback', - postLogoutRedirectUri: 'http://localhost:3000/', - // highlight-end - }), - }), - // ...other providers - ], -}; +`isSignInRedirected()` checks whether the URL matches an active sign-in session. If someone visits the callback route without one, this example returns them to the application home page instead of attempting to complete sign-in. + +Register the callback route in `app.routes.ts`. It must match the path of your redirect URI and must not require authentication. For example, use `callback` for a redirect URI ending in `/callback`: + +```ts title="app/app.routes.ts" +import { type Routes } from '@angular/router'; + +import { CallbackComponent } from './callback.component'; + +export const routes: Routes = [ + { path: 'callback', component: CallbackComponent }, + // ...other routes +]; ``` -### Implement sign-in and sign-out \{#implement-sign-in-and-sign-out} +The root component needs a `{{ error.message }}
+} @if (logto.isLoading()) { +Loading...
+} @else if (logto.isAuthenticated()) { + +} @else { + +} + +{{ error.message }}
+ } + @if (logto.isAuthenticated()) { + +{{ accessToken() }}
+ }
+ `,
+})
+export class ApiResourceComponent {
+ readonly logto = inject(LogtoService);
+ readonly accessToken = signal('');
+
+ async loadAccessToken() {
+ this.accessToken.set(await this.logto.getAccessToken('https://shopping.your-app.com/api'));
+ }
+}
+```
diff --git a/docs/quick-starts/framework/angular/code/_get-organization-access-token-code.md b/docs/quick-starts/framework/angular/code/_get-organization-access-token-code.md
new file mode 100644
index 00000000000..11083d2cbae
--- /dev/null
+++ b/docs/quick-starts/framework/angular/code/_get-organization-access-token-code.md
@@ -0,0 +1,59 @@
+```ts title="app/organizations.component.ts"
+import { Component, effect, inject, signal } from '@angular/core';
+import { LogtoService } from '@logto/angular';
+
+@Component({
+ selector: 'app-organizations',
+ standalone: true,
+ template: `
+ @if (logto.error(); as error) {
+ {{ error.message }}
+ } + @if (logto.isAuthenticated()) { +{{ organizationToken() }}
+ }
+ `,
+})
+export class OrganizationsComponent {
+ readonly logto = inject(LogtoService);
+ readonly organizationIds = signal