Storage means a space for putting things for future use. From a web application perspective, storage can be broadly classified into two types: server-side storage and client-side storage. Server-side storage points to the many different types of database storage like SQL, MYSQL, MongoDB, etc. Client-side storage means storing data in the browser itself so that it can be used when required without requesting the server-side database.
In this article, we'll discuss local storage and its usage from an Angular application's perspective. Let's start by trying to understand what local storage is.
What is Local Storage?
Local storage is client-side storage for web applications. It stays there as long as it's not cleared—unlike session storage, which lasts for the current browser tab session. Local storage provides up to 5MB of storage, allocated separately for each domain. For example, local storage for the website www.abc.com will be different from www.xyz.com.
Working with Local Storage
The local storage API provides a couple of methods to store, retrieve, remove and clear the storage. Let's see how to use these methods.
localStorage.setItem
The setItem
method allows you to add a value to the local storage. It stores data using a key value pair. For example:
localStorage.setItem('token','xhja787')
The above code stores the data xhja787
in a key called token
inside the browser local storage.
Note: localStorage only stores string values. To store objects or arrays, you need to use JSON.stringify to convert them into a string first.
Now, let's see how to access the stored data using getItem
localStorage.getItem
getItem
allows you to read back the data saved in local storage using the same key. For example, to fetch the data stored using the key token
, you can use the following method:
localStorage.getItem('token')
localStorage.removeItem
Once you are done using the data in the local storage, you can remove it using the removeItem
method. For example:
localStorage.removeItem('token')
localStorage.clear
You can clear all of the data out of the local storage using the clear method to wipe the slate clean.
localStorage.clear()
Now that's all plain JavaScript code to access the local storage. Using local storage in Angular is no different. First, let’s create an Angular application and then we'll create a service wrapper on top of the localStorage
API.
Creating the Angular App
You can create the Angular app using the Angular CLI.
ng new local-app
Once you have the Angular app, you can create an Angular service using the following command:
ng g service local
Let's add four wrapper methods to add, get, remove and clear storage. Here is how the service looks:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class LocalService {
constructor() { }
public saveData(key: string, value: string) {
localStorage.setItem(key, value);
}
public getData(key: string) {
return localStorage.getItem(key)
}
public removeData(key: string) {
localStorage.removeItem(key);
}
public clearData() {
localStorage.clear();
}
}
You can use the local service by injecting the service into your component. In this Angular example, to use the LocalService in the app.component.ts
file, you need to inject it by importing it in AppComponent
and creating an instance in the constructor method.
import { Component } from '@angular/core';
import { LocalService } from './local.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private localStore: LocalService) {
}
}
Local Storage Uses
Local storage can be used to store pretty much anything you like. It is most commonly used for storing JSON web tokens, user preferences and application settings such as themes.
How Secure is Local Storage?
When using local storage in Angular, the rule of thumb is to not store anything sensitive. Anything you store in local storage can be accessed by code in your browser. It's ok to store JSON web tokens since they’re already encrypted.
Another good rule of thumb is to encrypt the data before storing it in local storage and decrypt it when fetching from local storage. To encrypt and decrypt data in local storage, you can use a library such as crypto-js
.
To use it, first install it in your Angular project using npm
.
npm install crypto-js
npm i --save-dev @types/crypto-js
Once you have it installed, you can import the library in the LocalService
.
import * as CryptoJS from 'crypto-js';
Add the following two methods to encrypt and decrypt text:
private encrypt(txt: string): string {
return CryptoJS.AES.encrypt(txt, this.key).toString();
}
private decrypt(txtToDecrypt: string) {
return CryptoJS.AES.decrypt(txtToDecrypt, this.key).toString(CryptoJS.enc.Utf8);
}
Now, you can use the above two methods to encrypt and decrypt before storing and fetching data from local storage.
public saveData(key: string, value: string) {
localStorage.setItem(key, this.encrypt(value));
}
public getData(key: string) {
let data = localStorage.getItem(key)|| "";
return this.decrypt(data);
}
Here is how the complete local.service.ts
file looks:
import { Injectable } from '@angular/core';
import * as CryptoJS from 'crypto-js';
@Injectable({
providedIn: 'root'
})
export class LocalService {
key = "123";
constructor() { }
public saveData(key: string, value: string) {
localStorage.setItem(key, this.encrypt(value));
}
public getData(key: string) {
let data = localStorage.getItem(key)|| "";
return this.decrypt(data);
}
public removeData(key: string) {
localStorage.removeItem(key);
}
public clearData() {
localStorage.clear();
}
private encrypt(txt: string): string {
return CryptoJS.AES.encrypt(txt, this.key).toString();
}
private decrypt(txtToDecrypt: string) {
return CryptoJS.AES.decrypt(txtToDecrypt, this.key).toString(CryptoJS.enc.Utf8);
}
}
Now, let's test this by storing some text in the local storage. In your app.component.ts
file, import the LocalService
and create an instance of it in the constructor. In ngOnInit
, store the data in the local storage using the service method. Here is the app.component.ts
file:
import { Component } from '@angular/core';
import { LocalService } from './local.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'local-app';
constructor(private localStore: LocalService) {
}
ngOnInit(): void {
this.localStore.saveData('id', 'jk123');
}
}
Save the Angular app and run the application. After the app gets loaded, type in localStorage
from the browser console and you will be able to see the encrypted data in local storage.
{
"id": "U2FsdGVkX1+xovPDV0m0um6MPlrb+p5aG8Rb09TSWaM="
}
While trying to access the local storage data inside the application, you can get the decrypted data. For example, try to get the id data from local storage in ngOnInit
.
ngOnInit(): void {
this.localStore.saveData('id', 'jk123');
console.log('decrpted data ', this.localStore.getData('id'));
}
You will be able to see the decrypted data in your browser console.
Wrapping it Up
In this tutorial, you learned about what localStorage
is, how and when to use it, and how to encrypt and decrypt data on storing and fetching data respectively from localStorage
.
We hope you liked this tutorial, and if you want to learn how you can secure your Angular source code against theft and reverse-engineering, be sure to check our guide.