Azure AD B2C: Build Single-Page App on MSAL.js

Azure AD B2C: Build Single-Page App on MSAL.js

This simple sample demonstrates how to use the Microsoft Authentication Library for JavaScript (msal.js) to get an access token and call an API secured by Azure AD B2C.

This simple sample demonstrates how to use the Microsoft Authentication Library for JavaScript (msal.js) to get an access token and call an API secured by Azure AD B2C.

How to run this sample

There are two ways to run this sample:

  1. Using the demo environment - The sample is already configured to use a demo environment and can be run simply by downloading this repository and running the app on your machine. See steps below for Running with demo environment.
  2. Using your own Azure AD B2C tenant - If you would like to use your own Azure AD B2C configuration, follow the steps listed below for Using your own Azure AD B2C tenant.
Using the demo environment

This sample demonstrates how to sign in or sign up for an account at "Wingtip Toys" - the demo environment for this sample. Once signed-in, clicking on the Call Web API button shows the display name you used when you created your account.

Step 1: Clone or download this repository

From your shell or command line:

git clone https://github.com/Azure-Samples/active-directory-b2c-javascript-msal-singlepageapp.git

Step 2: Run the application

Make sure you've installed Node.

From your shell or command line:

cd active-directory-b2c-javascript-msal-singlepageapp
npm install && npm update
node server.js

The console window shows the port number for the web application

Listening on port 6420...

You can visit http://localhost:6420 and perform the following actions:

  1. Click the Login button to start the Azure AD B2C sign in or sign up workflow.
  2. Once signed in, you can click the Call Web API button to have your display name returned from the Web API call as a JSON object.
  3. Click Logout to logout from the application.
Using your own Azure AD B2C Tenant

In the previous section, you learned how to run the sample application using the demo environment. In this section, you'll learn how to configure this single page application sample and the related Node.js Web API with Azure AD B2C sample to work with your own Azure AD B2C Tenant.

Step 1: Get your own Azure AD B2C tenant

First, you'll need an Azure AD B2C tenant. If you don't have an existing Azure AD B2C tenant that you can use for testing purposes, you can create your own by following these instructions.

Step 2: Create your own policies

This sample uses a unified sign-up/sign-in policy. You can create your own unified sign-up/sign-in policy. You may choose to include as many or as few identity providers as you wish.

If you already have existing policies in your Azure AD B2C tenant, feel free to re-use those policies in this sample.

Step 3: Register your own Web API with Azure AD B2C

As you saw in the demo environment, this sample calls a Web API at https://fabrikamb2chello.azurewebsites.net. This demo Web API uses the same code found in the sample Node.js Web API with Azure AD B2C, in case you need to reference it for debugging purposes.

You must replace the demo environment Web API with your own Web API. If you do not have your own Web API, you can clone the Node.js Web API with Azure AD B2C sample and register it with your tenant.

How to setup and register the Node.js Web API sample

First, clone the Node.js Web API sample repository into its own directory, for example:

cd ..
git clone https://github.com/Azure-Samples/active-directory-b2c-javascript-nodejs-webapi.git

so the two folders active-directory-b2c-javascript-nodejs-webapi and active-directory-b2c-javascript-msal-singlepageapp are located side by side.

Second, follow the instructions at register a Web API with Azure AD B2C to register the Node.js Web API sample with your tenant. Registering your Web API allows you to define the scopes that your single page application will request access tokens for.

Provide the following values for the Node.js Web API registration:

  • Provide a descriptive Name for the Node.js Web API, for example, My Test Node.js Web API. You will identify this application by its Name whenever working in the Azure portal.
  • Mark Yes for the Web App/Web API setting for your application.
  • Set the Reply URL to http://localhost:5000. This is the port number that the Node.js Web API sample is configured to run on.
  • Set the AppID URI to hello. This AppID URI is a unique identifier representing this Node.jS Web API. The AppID URI is used to construct the scopes that are configured in you single page application's code. For example, in this Node.js Web API sample, the scope will have the value https://<your-tenant-name>.onmicrosoft.com/hello/demo.read
  • Create the application.
  • Once the application is created, open your My Test Node.js Web API application and then open the Published Scopes window (in the left nav menu) and add the scope demo.read followed by a description demoing a read scenario. Click Save.

Third, in the index.html file of the Node.js Web API sample, update the following variables to refer to your Web API registration.

var tenantID = "<your-tenant-name>.onmicrosoft.com";
var clientID = "<Application ID for your Node.js Web API - found on Properties page in Azure portal>";
var policyName = "<Name of your sign in / sign up policy, e.g. B2C_1_SiUpIn>";

Note

developers using the Azure China Environment, MUST use .b2clogin.cn authority, instead of login.chinacloudapi.cn.

In order to use .b2clogin.*, you will need to configure you application and set validateAuthority: false. Learn more about using b2clogin.

Lastly, to run your Node.js Web API, run the following command from your shell or command line

npm install && npm update
node index.js

Your Node.js Web API sample is now running on Port 5000.

Step 4: Register your own Web Application with Azure AD B2C

Next, you need to register your single page application in your B2C tenant.

Provide the following values for the Single Page Application registration:

  • Provide a descriptive Name for the single page application, for example, My Test SPA. You will identify this application by its Name whenever working in the Azure portal.
  • Mark Yes for the Web App/Web API setting for your application.
  • Set the Reply URL for your app to http://localhost:6420. This sample provided in this repository is configured to run on port 6420.
  • Create the application.
  • Once the application is created, open your My Test SPA and open the API Access window (in the left nav menu). Click Add and select the name of the Node.js Web API you registered previously, My Test Node.js Web API. Select the scope(s) you defined previously, for example, demo.read and hit Save.

Step 5: Configure the sample code to use your Azure AD B2C tenant

Now in the sample code, you can replace the single page application's demo environment configuration with your own tenant.

  1. Open the index.html file.
  2. Find the assignment for ClientID and replace the value with the Application ID for the single page application you registered in Step 4, for example the Application ID found in My Test SPA application in the Azure portal.
  3. Find the assignment for authority and replacing b2c_1_susi with the name of the policy you created in Step 2, and fabrikamb2c.onmicrosoft.com by the name of your Azure AD B2C tenant, for example https://<your-tenant-name>.b2clogin.com/<your-tenant-name>.onmicrosoft.com/<your-sign-in-sign-up-policy>
  4. Find the assignment for the scopes b2cScopes replacing the URL by the scope URL you created for the Web API, e.g. b2cScopes: ["https://<your-tenant-name>.onmicrosoft.com/helloapi/demo.read"]
  5. Find the assignment for API URL webApi replacing the current URL by the URL where you deployed your Web API in Step 4, e.g. `webApi: "https://fabrikamb2chello.azurewebsites.net/hello"

Your resulting code should look as follows:

<script class="pre">

// The current application coordinates were pre-registered in a B2C tenant.
var appConfig = {
      b2cScopes: ["https://fabrikamb2c.onmicrosoft.com/helloapi/demo.read"],
      webApi: "https://fabrikamb2chello.azurewebsites.net/hello"
    };
 </script>

const msalConfig = {
       auth: {
            clientId: "e760cab2-b9a1-4c0d-86fb-ff7084abd902", //This is your client ID
            authority: "https://fabrikamb2c.b2clogin.com/fabrikamb2c.onmicrosoft.com/b2c_1_susi", //This is your tenant info
            validateAuthority: false
        },
       cache: {
            cacheLocation: "localStorage",
            storeAuthStateInCookie: true
        }
    };

// instantiate MSAL
const myMSALObj = new Msal.UserAgentApplication(msalConfig);

Step 7: Run the sample

  1. Install the node dependencies if this is your first time running the app (e.g. if you skipped running in the demo environment):

    cd active-directory-b2c-javascript-msal-singlepageapp
    npm install && npm update
    
    
  2. Run the Web application

    node server.js
    
    
  3. Go to http://localhost:6420.

  4. Click the login button at the top of the application screen. The sample works exactly in the same way regardless of the account type you choose, apart from some visual differences in the authentication and consent experience. Upon successful sign in, the application screen will show buttons that allow you to call an API and sign out.

  5. Click on the Call Web API and see the textual representation of the JSON object that is returned. Make sure your Node.js Web API sample is still running on port 5000.

  6. Sign out by clicking the Logout button.

Optional

How to Upload multiple files to Azure Blob storage from Angular 8

How to Upload multiple files to Azure Blob storage from Angular 8

Upload to Azure Blob Storage with Angular 8. How to upload multiple files to blob storage in a browser with a Shared Access Signature (SAS) token generated from your back-end.

How to upload multiple files to blob storage in a browser with a Shared Access Signature (SAS) token generated from your back-end.

We’ll use Angular 8 and the @azure/storage-blob library to upload the files.

The final code is on Github which also contains examples on listing containers, blob items and deleting and downloading blob items.

We’ll go over

  • Creating a component to select and upload files
  • Creating a service to manage view state for the uploads
  • Securing the upload to Blob Storage with a SAS token
  • Creating a service to wrap the uploadBrowserData method in the @azure/storage-blob library to upload a file to Blob Storage
  • Creating a component to display upload progress
Create File Upload Component

The InputFileComponent component allows the user to select one or more files to upload

We’ll cover

  1. Selecting one or more files to upload

  2. Calling the method on the view state service to start the upload

import { Component, ElementRef, ViewChild } from '@angular/core';
import { BlobUploadsViewStateService } from '../services/blob-uploads-view-state.service';

@Component({
  selector: 'app-input-file',
  template: `
    <input
      style="display: none"
      type="file"
      #fileInput
      multiple="multiple"
      (change)="onSelected($event.target.files)"
    />
    <button (click)="showFileDialog()">Click here to Upload File</button>
  `
})
export class InputFileComponent {
  @ViewChild('fileInput', { static: false }) fileInput: ElementRef<
    HTMLInputElement
  >;

  constructor(private blobState: BlobUploadsViewStateService) {}

  onSelected(files: FileList): void {
    this.fileInput.nativeElement.value === '';
    this.blobState.uploadItems(files);
  }

  showFileDialog(): void {
    this.fileInput.nativeElement.click();
  }
}

What’s happening?

We’ve hidden the input and the file dialogue is opened with the button. The uploadItems method is called on the BlobUploadsViewStateService when the user selects files. We could add some validation here, but to me, it makes more sense to validate in the view state service.

Create uploads view state service

The BlobUploadsViewStateService service manages the shared view state for the components. I’m quite familiar with NGRX and redux patterns so I’ve created a service into which you can supply items to trigger actions and have observables listening for changes. It also means we can keep the business logic out of the components and the components will generally have a single responsibility.

We’ll cover

  1. Listing to an observable to trigger uploads

  2. Getting a SAS token

  3. Uploading a file to blob storage

  4. Keeping a list of all upload progress in the view state

import { Injectable } from '@angular/core';
import { from, OperatorFunction, Subject } from 'rxjs';
import { map, mergeMap, startWith, switchMap } from 'rxjs/operators';
import { BlobContainerRequest, BlobItemUpload } from '../types/azure-storage';
import { BlobSharedViewStateService } from './blob-shared-view-state.service';
import { BlobStorageService } from './blob-storage.service';

@Injectable({
  providedIn: 'root'
})
export class BlobUploadsViewStateService {
  private uploadQueueInner$ = new Subject<FileList>();

  uploadedItems$ = this.uploadQueue$.pipe(
    mergeMap(file => this.uploadFile(file)),
    this.blobState.scanEntries()
  );

  get uploadQueue$() {
    return this.uploadQueueInner$
      .asObservable()
      .pipe(mergeMap(files => from(files)));
  }

  constructor(
    private blobStorage: BlobStorageService,
    private blobState: BlobSharedViewStateService
  ) {}

  uploadItems(files: FileList): void {
    this.uploadQueueInner$.next(files);
  }

  private uploadFile = (file: File) =>
    this.blobState.getStorageOptionsWithContainer().pipe(
      switchMap(options =>
        this.blobStorage
          .uploadToBlobStorage(file, {
            ...options,
            filename: file.name + new Date().getTime()
          })
          .pipe(
            this.mapUploadResponse(file, options),
            this.blobState.finaliseBlobChange(options.containerName)
          )
      )
    );

  private mapUploadResponse = (
    file: File,
    options: BlobContainerRequest
  ): OperatorFunction<number, BlobItemUpload> => source =>
    source.pipe(
      map(progress => ({
        filename: file.name,
        containerName: options.containerName,
        progress: parseInt(((progress / file.size) * 100).toString(), 10)
      })),
      startWith({
        filename: file.name,
        containerName: options.containerName,
        progress: 0
      })
    );
}

What’s happening?

The public uploadItems method accepts a list of files and calls the next method on the uploadQueueInner$ subject. The uploadQueue$ getter is listening to the subject as an observable and will emit each file in the files list as a separate item. This is one place the files could be validated.

The uploadedItems$ property is listening to the uploadQueue$ and will call the uploadFile method in the service for each file item emitted. Something will need to subscribe to the uploadedItems$ for uploads to start and display upload progress (we’ll cover this below in the upload progress component)

The uploadFile method gets the latest SAS token and calls the uploadToBlobStorage on the Blob Storage Wrapper Service with the token and file details (we’ll cover this below).

The uploadToBlobStorage method returns an observable that emits the loadedBtyes each time it changes and can be used to track upload progress.

We then map the upload response to a percentage in the mapUploadResponse method and include extra detail. The method also has the startWith operator so any subscribers will be notified as soon as the upload starts rather than waiting for progress to be emitted.

We then call the finalise method when the upload is complete to refresh the items in the blob container.

The mapped response from the uploadFile method is then piped into a custom scan operator function to reduce the emitted values into an array. This allows us to store all uploads in progress and add further uploads when uploads are already in progress.

Secure the upload with a SAS token

The service above calls a method to get a SAS before every upload from a service. The method in this code example returns a hard codes SAS token I generated in the Azure portal, but in the real world, you would call an API to generate and return the SAS token. Here is a basic example in C# using the Azure.Storage.Blobs (v12.0.0) package to generate an Account SAS which can be used for many operations. You can also create SAS tokens for specific blob items or containers when you want/need to be more granular.

var key = Environment.GetEnvironmentVariable("AZURE_ACCOUNT_KEY");
var sharedKeyCredentials = new StorageSharedKeyCredential('<accountName>', key);
var sasBuilder = new AccountSasBuilder()
{
  StartsOn = DateTimeOffset.UtcNow,
  ExpiresOn = DateTimeOffset.UtcNow.AddMinutes(5),
  Services = AccountSasServices.Blobs,
  ResourceTypes = AccountSasResourceTypes.All,
  Protocol = SasProtocol.Https
};
sasBuilder.SetPermissions(AccountSasPermissions.All);

var sasToken = sasBuilder.ToSasQueryParameters(sharedKeyCredentials).ToString();
Wrap the uploadBrowserData method in the @azure/storage-blob library

We wrap the @azure/storage-blob library to return observables rather than promises as it works well when emitting progress events.

We’ll cover

  1. Creating an injection token which gets the blobServiceClient from the @azure/storage-blob library to make our service testable
  2. Calling the uploadBrowserData method and returning an observable of the loadedBytes

Here is a snippet from the full service

private uploadFile(blockBlobClient: BlockBlobClient, file: File) {
    return new Observable<number>(observer => {
      blockBlobClient
        .uploadBrowserData(file, {
          onProgress: this.onProgress(observer),
          blobHTTPHeaders: {
            blobContentType: file.type
          }
        })
        .then(
          this.onUploadComplete(observer, file),
          this.onUploadError(observer)
        );
    }).pipe(distinctUntilChanged());
  }

  private onUploadError(observer: Subscriber<number>) {
    return (error: any) => observer.error(error);
  }

  private onUploadComplete(observer: Subscriber<number>, file: File) {
    return () => {
      observer.next(file.size);
      observer.complete();
    };
  }

What’s happening?

The uploadToBlobStorage method in the wrapper service accepts the file to be uploaded and an object with the SAS token. It calls a method which will use the injected token service to return the blobServiceClient which was created using a connection string.

We then pass the BlockBlobClient created using the blobServiceClient and the file into the uploadFile method which wraps the uploadBrowserData method. We listen to the onProgress events and emit the value each time the progress changes. We then emit the file size and complete the observable when the upload completes.

Create a component to display upload progress

In this code example, the view state services manage the shared data and the components display the data. This good practice allows us to separate the file input and upload progress components and keeps our components small and have fewer responsibilities (hopefully just one).

import { Component } from '@angular/core';
import { BlobUploadsViewStateService } from '../services/blob-uploads-view-state.service';

@Component({
  selector: 'app-items-uploaded',
  template: `
    <h3>Uploads</h3>
    <div *ngFor="let upload of uploads$ | async">
      <pre>{{ upload | json }}</pre>
    </div>
  `
})
export class ItemsUploadedComponent {
  uploads$ = this.blobState.uploadedItems$;
  constructor(private blobState: BlobUploadsViewStateService) {}
}

What’s happening?

The uploads$ property is assigned the value from the uploadedItems$ property on the BlobUploadsViewStateService service we referenced above.

We then subscribe to the observable using the async pipe and display each item in the array.

Conclusion

This is one way the upload to Azure blob storage could be implemented and I’ve attempted to demonstrate a basic architecture for this as well as just showing example code.

You can also see a working example of the solution here. Apologies for the lack of styling.

Thank you for reading !

How to Use Cookies in Angular for Storing user’s Credentials

How to Use Cookies in Angular for Storing user’s Credentials

In this post, I will be explaining about using Cookies in Angular for Storing user’s Credentials

By using cookies we are going to store the user's login data, if the user's credentials are valid, then it will be directed to the Dashboard page.

In this post, I will be explaining about Angular cookies. So what is a cookie? Cookies are like a small package of information that is stored by the user’s browser. Cookies persist across multiple requests and browser sessions that should be set so that they can be a great method for authentication in web applications. Sometimes we will have some queries about which is to be used -- either local storage or cookies? Before that, I like to say that the cookies and local storage serve different purposes.

The local storage can be read on the client-side, whereas the cookies are being read on the server-side. The biggest difference is the data size is about to store, the local storage will give more space to store, whereas the cookie is limited by the size of to store.

As I said above the cookies are used on the server-side whereas the local storage is used on the client-side. The local storage is a way of storing the data in the client’s PC, by saving the key/ value pair in a web browser with no expiration date. We will discuss about using local storage in the next article, so coming to the point, as I said the cookies are a kind of small file that are stored on the user’s browser.

The cookie is a small table which will contain key and data values so, by using this it will be very useful to carry information from one session to another session. Once we are about to store data on the server without using cookies then it will be difficult to retrieve a particular user’s information without a login on each visit to that website.

So far we have seen about the overview of a cookie and the usage of it. Now in this article, I will explain about storing the username and password of a static user in the cookie table. So, I have created two components, namely the login component and dashboard component, and I have set a static username and password in authservice.ts file.

So, when a user logs in to the login form by providing his user’s credentials the authservice checks the input and redirects the user to the dashboard if the user’s credentials are valid. If the user’s credentials are not valid it will alert by throwing enter valid email or password. And if the dashboard page is being accessed by unauthorized usage the page will be redirected to the login page automatically.

Setting up

In order to use cookies in Angular, we need to install the Angular cookie library by using the following npm package manager.

npm install ngx-cookie-service –save

After installing the package manager, we need to import the cookie service in the inside of our modules.

I have used the ng zorro library UI for form design, and you can find more information about ng zorro from the following link. The next step is to design a login form. So, open login.component.html file and replace the following code.

<form fxFill #Login="ngForm" (ngSubmit)="onsubmit()">  
    <div nz-row>  
        <div nz-col nzMd="12" nzXs="24">  
            <hr />  
            <nz-form-item>  
                <nz-input-group>  
                    <div nz-col nzMd="11" nzXs="8">  
                        <nz-input-group nzPrefixIcon="user">  
                            <input type="text" nz-input name="Login_name" placeholder="User Name" id="userName"  
 
#userName="ngModel" [(ngModel)]="Obj.username">  
                            </nz-input-group>  
                            <div *ngIf="Login.submitted && userName.errors" style="color: red">  
                                <div *ngIf="userName.hasError('required')">  
  
Login ID is required  
  
</div>  
                            </div>  
                        </div>  
                    </nz-input-group>  
                </nz-form-item>  
                <nz-form-item>  
                    <div nz-col nzMd="11" nzXs="8">  
                        <nz-input-group nzPrefixIcon="lock">  
                            <input type="password" nz-input name="user_password" placeholder="Password"  
  
id="password" #password="ngModel" [(ngModel)]="Obj.password">  
                            </nz-input-group>  
                            <div *ngIf="Login.submitted && password.errors" style="color: red">  
                                <div *ngIf="password.hasError('required')">  
  
Password is required  
  
</div>  
                            </div>  
                        </div>  
                    </nz-form-item>  
                    <div class="button">  
                        <button nz-button nzType="primary">  
  
submit  
  
</button>  
                    </div>  
                </div>  
            </div>  
        </form>  

Now open login.component.ts file and replace the following code in it.

import {  
    Component,  
    OnInit  
} from '@angular/core';  
import {  
    FormGroup  
} from '@angular/forms';  
import {  
    AuthService,  
    User  
} from '../services/authservice.service';  
import {  
    Router,  
    ActivatedRoute  
} from '@angular/router';  
import {  
    CookieService  
} from 'ngx-cookie-service';  
@Component({  
    selector: 'nz-demo-card-simple',  
    templateUrl: './login.component.html'  
})  
export class LoginComponent implements OnInit {  
    Obj: User;  
    constructor(private srvLogin: AuthService, private router: Router, public activatedRoute: ActivatedRoute, private cookieService: CookieService) {  
        this.Obj = new User();  
    }  
    ngOnInit(): void {}  
    onsubmit(): void {  
        this.cookieService.set('username', this.Obj.username);  
        this.cookieService.set('password', this.Obj.password);  
        console.log(this.cookieService.get('username'));  
        console.log(this.cookieService.get('password'));  
        const a = this.Obj;  
        if (this.srvLogin.checkLogValues(this.Obj)) {  
            this.srvLogin.isloggedin = true;  
            console.log(this.srvLogin.isloggedin);  
            this.router.navigate(['/dashboard']);  
        }  
    }  
}  

The next point is to create an authentication service, we can create a service file by using the syntax.

ng generate service AuthService

The service name which I have given is Authservice and the service will be created and I have provided a default static username and password in service file so that the validation will be executed and redirected to another page (dashboard page) if the user’s credentials are being valid. Open Authservice service.ts file and replace the following code and import it in both service and as well in app-module.ts file.

import {  
    Injectable  
} from '@angular/core';  
import {  
    HttpClient  
} from '@angular/common/http';  
import {  
    CookieService  
} from 'ngx-cookie-service';  
@Injectable({  
    providedIn: 'root'  
})  
export class AuthService {  
    private username = 'vidya';  
    private password = '123456';  
    isloggedin = false;  
    constructor(private http: HttpClient) {}  
    checkLogValues(value: User): boolean {  
        if (this.username === value.username && this.password === value.password) {  
            console.log(this.username);  
            console.log(this.password);  
            // alert('Login valid');  
            return true;  
        } else {  
            alert('please enter valid data');  
            return false;  
        }  
    }  
}  
export class User {  
    username: string;  
    password: string;  
}  

After that create a component named as dashboard and open dashboard.component.html file and replace the following code.

<h3>Hello {{userDisplayName}} you are in Dashboard </h3>  
<div style="text-align:right">  
   <button nz-button nzType="danger" (click)="logout()">Logout</button>  
</div>  

The next step is to open dashboard.component.ts file and replace the following code inside it.

import {  
    Component,  
    OnInit  
} from '@angular/core';  
import {  
    AuthService,  
    User  
} from '../services/authservice.service';  
import {  
    Router,  
    ActivatedRoute  
} from '@angular/router';  
import {  
    CookieService  
} from 'ngx-cookie-service';  
@Component({  
    selector: 'dashboard',  
    templateUrl: './dashboard.component.html'  
})  
export class DashboardComponent implements OnInit {  
    Obj: User;  
    [x: string]: any;  
    userDisplayName = '';  
    password = '';  
    constructor(private srvLogin: AuthService, private router: Router, public activatedRoute: ActivatedRoute, private cookieService: CookieService) {  
        this.Obj = new User();  
        this.userDisplayName = this.cookieService.get('username');  
        this.password = this.cookieService.get('password');  
        this.Obj.username = this.userDisplayName;  
        this.Obj.password = this.password;  
        if (!srvLogin.checkLogValues(this.Obj)) {  
            router.navigate(['/login']);  
        }  
    }  
    ngOnInit(): void {}  
    logout(): void {  
        this.router.navigate(['/login']);  
        this.cookieService.deleteAll();  
    }  
}  

The following next step is to log in to the dashboard by providing the user’s credentials and after the valid login, we can see the user’s name in dashboard as a welcome note by using the user’s login name. So, after entering into the dashboard page open the developer’s tool in the browser and navigate -> Application and select cookies from storage. So, on that, we can see the user name and password have been stored in the cookie table.

So  far we have seen about storing the user’s details in the cookie table and now we can take an overview on clearing the cookies in the cookie table; for that use deleteall() method for clearing the cookies table if  the user is about to click-> logout button.

Conclusion

In this post, we have seen about using cookies in Angular for storing user’s credentials. I hope this article will be useful for you.

Angular Tutorial - Learn Angular from Scratch

Angular Tutorial - Learn Angular from Scratch

Angular Tutorial - Learn Angular from Scratch: This course is for beginners who are curious on how to get started with Angular. In this course you will learn how to download, install and play around with Angular. We teach you the main components of Angular, so that you can get up and running with it asap. You will learn now to start building applications with Angular.

This course is for beginners who are curious on how to get started with Angular. In this course you will learn how to download, install and play around with Angular. We teach you the main components of Angular, so that you can get up and running with it asap. You will learn now to start building applications with Angular.

Learning Angular can be a daunting experience that's why this course was created; to give you an easier learning experience with it.

What am I going to get from this course?

  • You will learn the mayor fundamentals of Angular
  • You will learn how to get up and running with Angular
  • You will learn to create Applications using Angular 5 and beyond

What you'll learn

  • You will learn the mayor fundamentals of Angular
  • You will learn how to get up and running with Angular
  • You will learn to create Applications using Angular 5 and beyond