Troubleshooting Angular 6: Issues with Route Guards not functioning as expected

Striving to enhance frontend security by restricting access to specific IDs. The goal is to redirect anyone trying to access routes other than /login/:id to a page-not-found error message if not already logged in, but encountering some issues.

Below are the routing table and guard implementations:

UPDATE: Issue resolved with updated code:

app-routing.module.ts

// Routing array - setting routes for each HTML page
const appRoutes: Routes = [{
    path: 'login/:id',
    canActivate: [AuthGuard],
    children: []
  },
  {
    path: '',
    canActivate: [AuthGuard],
    canActivateChild: [AuthGuard],
    children: [{
        path: '',
        redirectTo: '/courses',
        pathMatch: 'full'
      },
      {
        path: 'courses',
        component: CourseListComponent,
        pathMatch: 'full'
      },
      {
        path: 'courses/:courseId',
        component: CourseDetailComponent,
        pathMatch: 'full'
      },
      {
        path: 'courses/:courseId/unit/:unitId',
        component: CoursePlayComponent,
        children: [{
            path: '',
            component: CourseListComponent
          },
          {
            path: 'lesson/:lessonId',
            component: CourseLessonComponent,
            data: {
              type: 'lesson'
            }
          },
          {
            path: 'quiz/:quizId',
            component: CourseQuizComponent,
            data: {
              type: 'quiz'
            }
          }
        ]
      }
    ]
  },
  {
    path: '**',
    component: PageNotFoundComponent,
    pathMatch: 'full'
  }
];

auth.guard.ts

canActivate(route: ActivatedRouteSnapshot, state:
    RouterStateSnapshot): boolean |
  Observable<boolean> | Promise<boolean> {
    // saving the ID from route snapshot
    const id = +route.params.id;

    // handle logging with ID
    if (id) {
      this.authUserService.login(id);

      // return false on error
      if (this.authUserService.errorMessage) {
        this.router.navigate(["/page_not_found"]);
        return false;
      }

      // no errors - redirect to courses and continue
      else {
        this.router.navigate(["courses"]);
        return true;
      }
    }

    // already logged in and navigating between pages 
    else if (this.authUserService.isLoggedIn())
      return true;

    else {
      this.router.navigate(["/page_not_found"]);
      return false;
    }
  }

canActivateChild(route: ActivatedRouteSnapshot, state:
    RouterStateSnapshot): boolean |
  Observable<boolean> | Promise<boolean> {
    return this.canActivate(route, state);
  }

auth-user.service.ts

export class AuthUserService implements OnDestroy {

  private user: IUser;
  public errorMessage: string;
  isLoginSubject = new BehaviorSubject<boolean>(this.hasToken());

  constructor(private userService: UserService) {}

  login(id: number) {
    this.userService.getUser(id).subscribe(
      user => {
        this.user = user;
        localStorage.setItem('user', JSON.stringify(this.user));

        localStorage.setItem('token', 'JWT');
        this.isLoginSubject.next(true);
      },
      error => this.errorMessage = <any>error
    );
  }

  private hasToken(): boolean {
    return !!localStorage.getItem('token');
  }

  isLoggedIn(): Observable<boolean> {
    return this.isLoginSubject.asObservable();
  }

  logout() {
    localStorage.removeItem('user');
    localStorage.removeItem('token');
    this.isLoginSubject.next(false);
  }

  ngOnDestroy() {
    this.logout();
  }

Answer №1

I successfully resolved the issue by making some modifications. I included an empty array in the route login/:id under children and switched isLoggedIn to a behaviorSubject to maintain the token's consistency even after refreshing or navigating between pages. These changes proved effective, and I have updated the code in the post for everyone's reference.

Answer №2

modify this line:

const id = route.params.id;

to

const id = +route.params.id; // converting from string to number (originally a string from route params)

Additionally, reconsider navigating to a page not found with ['**']

Rather use: ['/page_not_found']

I realize that 'page_not_found' is not actually in your route, but that's intentional, as it will redirect the user to a page not found as per your requirement

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Merge the values of checkboxes into a single variable

How can I gather all the checkbox values from my list and combine them into a single variable? This is the structure of my HTML: <div class="card" *ngFor="let event of testcases" > <input class="form-check-input" ...

Troubleshooting JWT Session Errors in Next Auth / NextJS

Hello, I am in need of assistance with the authentication process using the getServerSession method of next-auth. I am utilizing the magic link login with the prism adapter. The frontend session seems to be working fine and the sessions are correctly stor ...

Leverage JavaScript libraries utilizing namespaces within your Angular application

I have a unique JavaScript library that includes functions organized within namespaces. For example: var testNamespace = { insideFunction: function(str) { alert(atr); } }; Now, I am trying to integrate these functions into my Angular app.c ...

Differentiating navigation design in various views of Angular 4

I am utilizing a shared navigation with content that changes via RouterModule. Is there a way to modify the design of the navigation in different views? <app-navigation></app-navigation> <router-outlet></router-outlet> For example ...

What is the best method for placing a single character from a user's quote into a table?

this is an example of some HTML code <section class="insertionCitation"> <label>Quote:</label> <input #quote (keyUp.Enter)='validateQuote(quote.value)'> </section> `- how can I display one letter ...

Which release of "ngx-bootstrap" is compatible with "Angular 17"?

Here's the scoop I attempted to download ngx-bootstarp but couldn't find a suitable version. I searched online, but there was no information available. Checking the list on the Angular Bootstrap official website, I noticed that version 17.0.0 ha ...

The child module is unable to locate the route URL for the parent module

I'm new to Angular and I'm working on organizing my code into modules. So far, I have an admin module that responds to the /admin request, but now I want to add a child module called Portfolio Module. Everything is working fine, except for the f ...

Using Owl Carousel 2 and other jQuery plugins in Angular 4 TypeScript classes: A step-by-step guide

I have been facing challenges trying to incorporate jQuery plugins into an Angular 4 TypeScript class. Despite multiple attempts, I have not been able to achieve my goal. I tried various methods, but the HTML component view in Angular 4 does not seem to s ...

What is the best method for installing the most recent 1.1.5 version of is-callable?

After running the command npm install, an error occurred: npm ERR! code ETARGET npm ERR! notarget No matching version found for is-callable@^1.1.5. npm ERR! notarget In most cases you or one of your dependencies are requesting npm ERR! notarget a ...

The ngAfterViewInit lifecycle hook does not get triggered when placed within ng-content

The ngAfterViewInit lifecycle hook isn't triggered for a Component that is transcluded into another component using <ng-content>, as shown below: <app-container [showContent]="showContentContainer"> <app-input></app-input> ...

Exploring the capabilities of Angular2 and Jasmine through testing

I have been working on a basic spec for a component and I'm curious about the test's behavior. The test is designed to verify if a component is successfully created. It seems that when the test is executed, it first compiles and runs the Compone ...

Is there a way to duplicate content (also known as *ngFor) without using a surrounding element?

I am working on an Angular 4 component that utilizes a 2d array structure. I have an array of sections, each containing an array of links. My goal is to display them in a flat format: <ul> <div *ngFor="let section of all_sections"> <l ...

Using React for passing data

In the snippet found in "CameraPage.tsx", there is a logical function that is responsible for fetching camera images. This function simply makes a GET request to search for images stored in the backend, which will later be displayed on the FrontEnd. The op ...

Tips for postponing the listening observer experience?

One of my components is triggered by a conditional show: <app-list *ngIf="show"></app-list> At the same time, I emit an event in the same place where I activate this component: this.tabsEvens.emitMoveToVersions(version); this.router.navigate ...

When an Angular2 application is deployed on a server running NginX, child components fail to load

After deploying my Angular2 app on a server as a Docker image and serving it with NginX, I encountered an unexpected issue. When I ran the webpack-dev-server locally to verify if the build was successful, everything looked fine https://i.sstatic.net/wQQ7 ...

When the passport authentication process returns an HTTP 500 error, it fails to execute the route methods even after successfully verifying the

Here is the structure of my router method: router.get("/getData", passport.authenticate("consumer-validation"), getAccountData ); I am using a strategy defined from passport-custom const consumerValidationStrategy = new Strategy( ...

Troubleshooting Node.js TypeScript breakpoints in Visual Studio Code

I've attempted multiple solutions, but none seem to be working for me. Although the code is running, I'm having trouble setting breakpoints and debugging it. Can you offer any assistance? Below is the configuration script I've tried in VSCo ...

Is it possible for Angular2 to map a lone JSON object?

Dealing with a JSON response that is a single object, rather than an array, can be tricky. Recently in my project, I encountered a situation where I needed to map and use such a response from an API to fill out a template. It seemed like a simple task at f ...

Instructions for inserting a key into the browser's 'Local Storage' utilizing the robot framework

After successfully setting a Cookie, I realized that the login mechanism requires me to set a key in the 'Local Storage' Here is the code snippet: Successful Login Create Session loginsession url=${base_url} verify=true ${data} ...

Issue with MIME handling while utilizing Vue-Router in combination with Express

Struggling to access a specific route in Express, I keep encountering an error in my browser. Additionally, when the Vue application is built, only the Home page and the 404 page seem to work properly, while the rest display a default empty HTML layout. F ...