токен не отправляется на сервер в angular WWW-Authenticate: Bearer и появляется ошибка 401 - PullRequest
0 голосов
/ 09 июля 2020

Я новичок в angular, и я создал небольшое приложение на основе ролей, используя Angular 9 для внешнего интерфейса и Asp. net ядра. когда я вхожу в систему / выхожу из системы, приложение работает правильно без каких-либо проблем, и я могу получить доступ к контроллерам без авторизации из внешнего интерфейса, но когда я хочу получить доступ к контроллеру авторизации («компания»), я получаю ошибку 401. enter image description here

enter image description here when I check the "Network" tab in my browser I can see that "WWW-Authenticate: Bearer"

enter image description here and I checked in Microsoft Docs , затем я нахожу

Обратите внимание, что ответ включает заголовок Www-Authenticate с задачей, установленной на Bearer. Это означает, что сервер ожидает токен-носитель.

Я почти уверен, что проблема не в бэкэнде, потому что я также проверил бэкэнд с помощью Postman, и он работает правильно

Итак Я помещаю сюда код

auth.service.ts:

    @Injectable({
    providedIn: 'root'
  })
  export class AuthService {
    baseUrl = environment.apiUrl + 'authentication/';  //environment.apiUrl + 'auth/';
    jwtHelper = new JwtHelperService();
    decodedToken: any;
    currentUser: User;      
  //================================================================================================
    constructor(private myalertService: MyalertService,private http: HttpClient) {}
  //================================================================================================
    login(model: any) {
      return this.http.post(this.baseUrl + 'login', model).pipe(
        map((response: any) => {
          const user = response;
          if (user) {
            localStorage.setItem('token', user.user.token);
            localStorage.setItem('user', JSON.stringify(user.user));
            this.decodedToken = this.jwtHelper.decodeToken(user.user.token);
            this.currentUser = user.user;             
           
          }
        })
      );
    } 
  //================================================================================================
    loggedIn() {
      const token = localStorage.getItem('token');
      return !this.jwtHelper.isTokenExpired(token);
    }
  //================================================================================================
    roleMatch(allowedRoles): boolean {
      let isMatch = false;
      const userRoles = this.decodedToken.role as Array<string>;   
 
      allowedRoles.forEach(element => {
        if (userRoles.includes(element)) {
          isMatch = true;
          return;
        }
      });
      return isMatch;
    }   
      //===================================================================================================
  }

company.service.ts:

@Injectable({
  providedIn: 'root'
})
export class CompanyService {
   result = false;
   baseUrl = environment.apiUrl + 'companies';

      
constructor(private myalertService: MyalertService,private http: HttpClient  ) { }
 //=============================================================================================

  getCompaniesList(page?,itemsPerPage?,srchMdl?): Observable<PaginatedResult<Company[]>> {

      const paginatedResult : PaginatedResult<Company[]> = new PaginatedResult<Company[]>();
  
      let params = new HttpParams();       

      if (page != null && itemsPerPage != null) {
        params = params.append('pageNumber', page);
        params = params.append('pageSize', itemsPerPage);
       
      } 
   
      if (srchMdl != null) {

              if(srchMdl.name != "" && srchMdl.name != null ) params = params.append('name',srchMdl.name);
              if(srchMdl.address != "" && srchMdl.address != null ) params = params.append('address',srchMdl.address);
              if(srchMdl.country != "" && srchMdl.country != null) params = params.append('country',srchMdl.country);
              if(srchMdl.searchOperator != "" && srchMdl.searchOperator != null) params = params.append('searchOperator',srchMdl.searchOperator); else params = params.append('searchOperator','AND');
              if(srchMdl.sortBasedOn != "" && srchMdl.sortBasedOn != null) params = params.append('orderBy',srchMdl.sortBasedOn);
      }

    

            return this.http.get<Company[]>(this.baseUrl , { observe: 'response', params},)
            .pipe(
              map(response => {
                paginatedResult.result = response.body;
                if (response.headers.get('X-Pagination') != null) {
                  paginatedResult.pagination = JSON.parse(response.headers.get('X-Pagination'));  
                }             
                return paginatedResult;
              })
            );
    } 
    //=============================================================================================
  }

company.resolver.ts:

    @Injectable()
export class CompanyResolver implements Resolve<Company[]> {
    pageNumber = 0;
    pageSize = 5;

    constructor(private companyService: CompanyService, private router: Router,
        private alertify: MyalertService) {}

    resolve(route: ActivatedRouteSnapshot): Observable<Company[]> {
        return this.companyService.getCompaniesList(this.pageNumber, this.pageSize).pipe(
            catchError(error => {
                this.alertify.error('Problem retrieving data');
                this.router.navigate(['/home']);
                return of(null);
            })
        );
    }
}

hasRole.directive.ts:

@Directive({
    selector: '[appHasRole]'
  })
  export class HasRoleDirective implements OnInit {
    @Input() appHasRole: string[];
    isVisible = false;
  
    constructor(
      private viewContainerRef: ViewContainerRef,
      private templateRef: TemplateRef<any>,
      private authService: AuthService) { }
  
    ngOnInit() {
      const userRoles = this.authService.decodedToken.role as Array<string>;
        
      if (!userRoles) {
        this.viewContainerRef.clear();
      }

      if (this.authService.roleMatch(this.appHasRole)) {
        if (!this.isVisible) {
          this.isVisible = true;
          this.viewContainerRef.createEmbeddedView(this.templateRef);
        } else {
          this.isVisible = false;
          this.viewContainerRef.clear();
        }
      }
    }
  
  }

auth.guard.ts:

@Injectable({
    providedIn: 'root'
  })
  export class AuthGuard implements CanActivate {
    constructor(  private authService: AuthService, 
                  private router: Router,
                  private alertify: MyalertService) {}
  
    canActivate(next: ActivatedRouteSnapshot): boolean {    
    
     const roles = next.firstChild.data['userRoles'] as Array<string>;
     console.log('auth.guard.ts');
     console.log(roles);
      if (roles) {
        const match = this.authService.roleMatch(roles);
        if (match) {
          return true;
        } else {        
          this.alertify.error('You are not authorized to access this area');
        }
      }
  
      if (this.authService.loggedIn()) {
        return true;
      }
  
      this.alertify.error('You shall not pass!!!');
      this.router.navigate(['/company']);
      return false;
    }
  }

routes.ts:

export const appRoutes: Routes = [
    {path: '', component: HomeComponent},
    {
        path: '',
         runGuardsAndResolvers: 'always',
         canActivate: [AuthGuard],
        children: [
    
           {path: 'company', component: CompanyComponent, data: {userRoles: ['Administrator', 'Manager']}},
      
            {path: 'register', component: RegisterComponent },
            {path: 'memberList', component: MemberListComponent},
    
            {path: 'admin', component: AdminPanelComponent, data: {userRoles: ['Administrator', 'Manager']}},

        ]
    },
    {path: '**', redirectTo: '', pathMatch: 'full'},
];

приложение .module.ts:

export function tokenGetter() {
   return localStorage.getItem('token');
 }

@NgModule({
   declarations: [        
      CompanyComponent,      
      HomeComponent,         
      NavBarComponent,
      HasRoleDirective
   ],
   imports: [      
      ReactiveFormsModule,
      BrowserModule,
      AppRoutingModule,
      BrowserAnimationsModule,
      MatSliderModule,
      MatButtonModule,
      MatIconModule,
      MatDividerModule,
      MatSnackBarModule,
      MatTableModule,
      HttpClientModule,
      FormsModule,
      MatFormFieldModule,
      MatCardModule,
      MatInputModule,
      MatToolbarModule,
      MatPaginatorModule,
      MatProgressSpinnerModule,
      MatSelectModule,
      MatRadioModule,
      FlexLayoutModule,
      RouterModule.forRoot(appRoutes),
      JwtModule.forRoot({
         config: {
            //This automatically adds the token to the request.
           tokenGetter: tokenGetter,
          
           whitelistedDomains:['localhost:5001'],
           blacklistedRoutes: ['localhost:5001/api/authentication'],
          
         }
       })
   ],
   providers: [
      CompanyResolver,
      AuthService,
      AuthGuard,
      CompanyService
   ],
   bootstrap: [
      AppComponent
   ]
})
export class AppModule { }

navBar.component.ts:

xport class NavBarComponent implements OnInit {
  model: any = {};

  constructor( 
    private authService: AuthService ,
    private alertify: MyalertService ,
    private router: Router
    ) {}

  ngOnInit() {
    this.model.username = 'abcdefgh';
    this.model.password = 'Pass12345678';
  }


  login() {  

    this.authService.login(this.model).subscribe(next => {
      this.alertify.success('Logged in successfully');
     
    }, error => {
      this.alertify.error(error);
    }, () => {
      

    });
  }


  loggedIn() {
    const token = localStorage.getItem('token');
    return !!token;
  }
  logout() {
    localStorage.removeItem('token');
    localStorage.removeItem('user');
    this.authService.decodedToken = null;
    this.authService.currentUser = null;
    this.alertify.success('logged out');
    this.router.navigate(['/home']);
  }
}

navBar.component. html:

 <mat-toolbar color="primary">
 
  <span class="fill-remaining-space"></span>
 
  <button mat-button routerLink="login">Login</button>
  <button mat-button (click)="logout()">Logout</button>

  <ul *ngIf="loggedIn()" >
     <button *appHasRole="['Admin','Manager']" mat-button [routerLink]="['/company']">company Manager</button>
     <button  mat-button [routerLink]="['/memberList']">member List</button>
  </ul>



  
  
  <form #loginForm="ngForm" *ngIf="!loggedIn()"  class="form-inline my-2 my-lg-0" (ngSubmit)="login()">  

    <mat-form-field appearance="legacy" >    
      <input matInput name="username" placeholder="Username " [(ngModel)]="model.username" >
    </mat-form-field>

    <mat-form-field appearance="legacy" > 
      <input matInput name="password" placeholder="Password " [(ngModel)]="model.password">
    </mat-form-field>

    <button mat-raised-button color="accent"   type="submit"> Login </button>   
  </form>
    
</mat-toolbar>

1 Ответ

0 голосов
/ 09 июля 2020

Бэкэнд ожидает токен Bearer в каждом запросе. В ваших заголовках ответа отсутствует токен носителя.

Вы можете установить заголовок в перехватчике как

const token = this.oauthService.accessToken;
const authToken = "Bearer " + token;

заголовки: request.headers.set("Authorization", authToken).

введите описание изображения здесь

...