Creating a Protected Dashboard

What We Are Doing:

  • Adding a protected resource (e.g., /dashboard) that only verified users can access.

  • Decoding the access_token to display user information extracted from the credential.

Why: To show the end result of verification, we will display a dashboard page that uses the credential data.

Steps: Create public/dashboard.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>Dashboard</title>
</head>
<body>
<h2>Welcome to the Dashboard!</h2>
<p>DID: <span id="did"></span></p>
<p>First Name: <span id="first-name"></span></p>
<p>Last Name: <span id="last-name"></span></p>
<p>Age: <span id="age"></span></p>

<script>
    (async () => {
        const token = localStorage.getItem("access_token");
        if (!token) return;

        const res = await fetch('/authorization/decode-access-token', {
            headers: { Authorization: `Bearer ${token}` }
        });
        const data = await res.json();
        document.getElementById("did").innerText = data.did;
        document.getElementById("first-name").innerText = data.formData.firstName;
        document.getElementById("last-name").innerText = data.formData.lastName;
        document.getElementById("age").innerText = data.formData.age;
    })();
</script>
</body>
</html>

Add a route to decode the token and extract data in src/authorization-routes.js:

import { Router } from "express";
import jwt from "jsonwebtoken";
import { VerifiablePresentation } from "@empe/identity";

import dotenv from "dotenv";

dotenv.config();

const router = Router();
const JWT_SECRET = process.env.JWT_SECRET;

router.get("/decode-access-token", (req, res) => {
    const authHeader = req.headers["authorization"];
    const access_token = authHeader?.split(" ")[1];
    if (!access_token) return res.status(401).json({ error: "Unauthorized" });

    try {
        const decoded = jwt.verify(access_token, JWT_SECRET);
        let formData = {};

        if (decoded.vp) {
            const vp = VerifiablePresentation.fromJSON(decoded.vp);
            vp.verifiableCredentials().forEach((vc) => {
                formData = { ...formData, ...vc.credentialSubject() };
            });
        }

        res.json({
            did: decoded.sub,
            formData,
        });
    } catch (error) {
        res.status(500).json({ error: "Internal server error" });
    }
});

router.get("/dashboard", (req, res) => {
    res.sendFile("dashboard.html", { root: "public" });
});

export default router;

Now, after verification, the user is redirected to /dashboard, and their credential info is displayed.

Last updated