angulartypescriptsanctum

How to create a guard for guest users in Angular to authenticate with sanctum only


I have a forum like application that uses Laravel for the back-end, sanctum for authentication and Angular for the front-end

I need guest users to access the home page and request the list of questions to show from the Laravel api but I need to prevent them from accessing the editor page for creating questions

the api endpoints are protected by auth:sanctum middleware so guest users need to request a token to access the api.

Instead Users authenticated also via front-end (logged in Users) should access guests forbidden routes.

For logged in users I've created this guard in angular:

export class AuthGuardGuard implements CanActivate {
  constructor(private authService : AuthService){ }
  activate = false
  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    this.authService.getUser()
      .subscribe(
        res => this.activate = true
      )
    return this.activate;
  }

}

but it's not clear to me how should I handle guest users authentications


Solution

  • I solved the problem by making the read routes of my api free from sanctum middleware like this:

    Route::prefix('user')->group(function(){
        Route::get('/{id}', [UserController::class, 'show']);
        Route::middleware('auth:sanctum')->put('/{id}', [UserController::class, 'update']);
    });
    ;
    
    
    Route::prefix('questions')->group(function () {
        Route::get('', [QuestionController::class, 'index']);
        Route::get('/{id}', [QuestionController::class, 'show']);
        Route::middleware('auth:sanctum')->post('', [QuestionController::class, 'store']);
        Route::get('/user/{userId}', [QuestionController::class, 'getByUserId']);
        Route::get('/category/{categoryId}', [QuestionController::class, 'getByCategoryId']);
    });
    

    and making an auth guard for logged-In only routes:

    canActivate(
        route: ActivatedRouteSnapshot,
        state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
        this.authService.getUser()
          .subscribe(
            res => {
              this.activate = true
            },
            err => {
              this.router.navigate(['/login'])
              this.activate = false
            }
          )
        return this.activate;
      }
    

    and protected the /editor route like so:

      {path: 'editor', component: EditorDetailsComponent, canActivate : [AuthGuard]},
    
    

    with this, users that have no account can read the questions but they are redirected to login if they try to create a new question by accessing the /editor route