从Auth0可观察到的角度获取名称

问题描述 投票:0回答:3

我想在登录后从Auth0 userProfile $中提取名称。因此,我可以使用它在我们的数据库中创建顾问。我对可观察和订阅并不熟悉。我试图在下面的代码中使用它。当我登录内部订阅时,可以看到要添加到帖子要求中的名称。但是当我尝试使用它时,只会给我一个空的订阅。

dashboard.component.ts
```typescript
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { ApiService } from '../services/api.service';
import { AuthService } from 'src/app/auth/auth.service';

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.scss'],
})
export class DashboardComponent implements OnInit {
  id= '';


  navigateSkillplatform() {
    this.router.navigate(['skillplatform', this.id]);
  }

  constructor(private router: Router, private api: ApiService, private auth: AuthService) {}

  ngOnInit(): void {


    var consultant = { Name: this.auth.userProfile$.subscribe(consultant => console.log("test", consultant.name)) };
    console.log(consultant.Name)
    // if (this.auth.loggedIn) {
    //   this.api.createConsultant(consultant).subscribe(
    //     response => {
    //       console.log("POST create consultant response:," , 
    //       response);
    // })
    // }
  }
}
```

Browser console output
<pre>
dashboard.component.ts:24 test Imke Van Rompa
dashboard.component.ts:25 
Subscriber {closed: false, _parentOrParents: null, _subscriptions: Array(1), syncErrorValue: null, syncErrorThrown: false, …}
closed: false
_parentOrParents: null
_subscriptions: [SubjectSubscription]
syncErrorValue: null
syncErrorThrown: false
syncErrorThrowable: true
isStopped: false
destination: SafeSubscriber {closed: false, _parentOrParents: null, _subscriptions: null, syncErrorValue: null, syncErrorThrown: false, …}
__proto__: Subscription
</pre>

Auth.service
```
    import { Injectable } from '@angular/core';
    import createAuth0Client from '@auth0/auth0-spa-js';
    import Auth0Client from '@auth0/auth0-spa-js/dist/typings/Auth0Client';
    import { authConfig } from '../../environments/environment';
    import { from, of, Observable, BehaviorSubject, combineLatest, throwError } from 'rxjs';
    import { tap, catchError, concatMap, shareReplay } from 'rxjs/operators';
    import { Router } from '@angular/router';

    @Injectable({
      providedIn: 'root',
    })
    export class AuthService {
      // Create an observable of Auth0 instance of client
      auth0Client$ = (from(
        createAuth0Client({
          domain: authConfig.domain,
          client_id: authConfig.clientId,
          redirect_uri: `${window.location.origin}`,
          audience: authConfig.audience,
        })
      ) as Observable<Auth0Client>).pipe(
        shareReplay(1), // Every subscription receives the same shared value
        catchError(err => throwError(err))
      );

      // Manage Acces Token
      // Observable method to retrieve access token and make it available for use in application
      getTokenSilently$(options?): Observable<string> {
        return this.auth0Client$.pipe(
          concatMap((client: Auth0Client) => from(client.getTokenSilently(options)))
        );
      }

      // Define observables for SDK methods that return promises by default
      // For each Auth0 SDK method, first ensure the client instance is ready
      // concatMap: Using the client instance, call SDK method; SDK returns a promise
      // from: Convert that resulting promise into an observable
      isAuthenticated$ = this.auth0Client$.pipe(
        concatMap((client: Auth0Client) => from(client.isAuthenticated())),
        tap(res => (this.loggedIn = res))
      );
      handleRedirectCallback$ = this.auth0Client$.pipe(
        concatMap((client: Auth0Client) => from(client.handleRedirectCallback()))
      );
      // Create subject and public observable of user profile data
      private userProfileSubject$ = new BehaviorSubject<any>(null);
      userProfile$ = this.userProfileSubject$.asObservable();
      // Create a local property for login status
      loggedIn: boolean = null;

      constructor(private router: Router) {
        // On initial load, check authentication state with authorization server
        // Set up local auth streams if user is already authenticated
        this.localAuthSetup();
        // Handle redirect from Auth0 login
        this.handleAuthCallback();
      }

      // When calling, options can be passed if desired
      // https://auth0.github.io/auth0-spa-js/classes/auth0client.html#getuser
      getUser$(options?): Observable<any> {
        return this.auth0Client$.pipe(
          concatMap((client: Auth0Client) => from(client.getUser(options))),
          tap(user => this.userProfileSubject$.next(user))
        );
      }

      private localAuthSetup() {
        // This should only be called on app initialization
        // Set up local authentication streams
        const checkAuth$ = this.isAuthenticated$.pipe(
          concatMap((loggedIn: boolean) => {
            if (loggedIn) {
              // If authenticated, get user and set in app
              // NOTE: you could pass options here if needed
              return this.getUser$();
            }
            // If not authenticated, return stream that emits 'false'
            return of(loggedIn);
          })
        );
        checkAuth$.subscribe();
      }

      login(redirectPath: string = '/') {
        // A desired redirect path can be passed to login method
        // (e.g., from a route guard)
        // Ensure Auth0 client instance exists
        this.auth0Client$.subscribe((client: Auth0Client) => {
          // Call method to log in
          client.loginWithRedirect({
            redirect_uri: `${window.location.origin}`,
            appState: { target: redirectPath },
          });
        });
      }

      private handleAuthCallback() {
        // Call when app reloads after user logs in with Auth0
        const params = window.location.search;
        if (params.includes('code=') && params.includes('state=')) {
          let targetRoute: string; // Path to redirect to after login processsed
          const authComplete$ = this.handleRedirectCallback$.pipe(
            // Have client, now call method to handle auth callback redirect
            tap(cbRes => {
              // Get and set target redirect route from callback results
              targetRoute = cbRes.appState && cbRes.appState.target ? cbRes.appState.target : '/';
            }),
            concatMap(() => {
              // Redirect callback complete; get user and login status
              return combineLatest([this.getUser$(), this.isAuthenticated$]);
            })
          );
          // Subscribe to authentication completion observable
          // Response will be an array of user and login status
          authComplete$.subscribe(([user, loggedIn]) => {
            // Redirect to target route after callback processing
            this.router.navigate([targetRoute]);
          });
        }
      }

      logout() {
        // Ensure Auth0 client instance exists
        this.auth0Client$.subscribe((client: Auth0Client) => {
          // Call method to log out
          client.logout({
            client_id: authConfig.clientId,
            returnTo: window.location.origin,
          });
        });
      }
    }
    ```

    I am sure there is going to be a simple answer for this that I just didn't think of yet.
angular observable auth0 subscribe
3个回答
0
投票

我认为您应该只订阅并映射到订阅中的名称。

ngOnInit(): void {
    const consultant = {}
    this.auth.userProfile$.subscribe(result=> {
          console.log("test", result.name)
          consultant.name = result.name
    });
}

0
投票

也许使用应该改变

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { ApiService } from '../services/api.service';
import { AuthService } from 'src/app/auth/auth.service';

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.scss'],
})
export class DashboardComponent implements OnInit {
  id= '';


  navigateSkillplatform() {
    this.router.navigate(['skillplatform', this.id]);
  }

  constructor(private router: Router, private api: ApiService, private auth: AuthService) {}

  ngOnInit(): void {


    var consultant = { Name: this.auth.userProfile$.subscribe(consultant => console.log("test", consultant.name)) };
    console.log(consultant.Name)
    // if (this.auth.loggedIn) {
    //   this.api.createConsultant(consultant).subscribe(
    //     response => {
    //       console.log("POST create consultant response:," , 
    //       response);
    // })
    // }
  }
}

收件人

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Router } from '@angular/router';
import { ApiService } from '../services/api.service';
import { AuthService } from 'src/app/auth/auth.service';
import { takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.scss'],
})
export class DashboardComponent implements OnInit, OnDestroy {
  id= '';
  consultant = null;
  onDestroy = new Subject<void>();

  navigateSkillplatform() {
    this.router.navigate(['skillplatform', this.id]);
  }

  constructor(private router: Router, private api: ApiService, private auth: AuthService) {}

  ngOnInit(): void {


    this.auth.userProfile$.pipe(takeUntil(this.onDestroy)).subscribe(consultant => 
        this.consultant = consultant;
        // Do whaterever you want with the user.
        console.log(this.consultant)
    );

    }
  }

  ngOnDestroy() { this.onDestroy.emit(); }
}

0
投票

尝试这样的事情:

export class DashboardComponent implements OnInit {
  id= '';
  consultantName;

  navigateSkillplatform() {
    this.router.navigate(['skillplatform', this.id]);
  }

  constructor(private router: Router, private api: ApiService, private auth: AuthService) 
  {}

  ngOnInit(): void {
    this.auth.userProfile$.subscribe(consultant => this.consultantName = consultant.name);

    console.log(this.consultantName)
    // Now you have name for your consultant and you can make post to your db
    if (this.auth.loggedIn && this.consultantName) {
       this.api.createConsultant(this.consultantName).subscribe(
         response => {
           console.log("POST create consultant response:," , 
           response);
      })
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.