diff --git a/src/widgets/npm/component.jsx b/src/widgets/npm/component.jsx
index b35e27c8..92aef035 100644
--- a/src/widgets/npm/component.jsx
+++ b/src/widgets/npm/component.jsx
@@ -11,7 +11,7 @@ export default function Component({ service }) {
 
   const { data: infoData, error: infoError } = useWidgetAPI(widget, "nginx/proxy-hosts");
 
-  if (infoError) {
+  if (infoError || infoData?.error) {
     return <Container error={t("widget.api_error")} />;
   }
 
diff --git a/src/widgets/npm/proxy.js b/src/widgets/npm/proxy.js
index eed43b57..ff15db62 100644
--- a/src/widgets/npm/proxy.js
+++ b/src/widgets/npm/proxy.js
@@ -1,6 +1,33 @@
+import cache from "memory-cache";
+
 import getServiceWidget from "utils/config/service-helpers";
 import { formatApiCall } from "utils/proxy/api-helpers";
+import { httpProxy } from "utils/proxy/http";
 import widgets from "widgets/widgets";
+import createLogger from "utils/logger";
+
+const proxyName = "npmProxyHandler";
+const tokenCacheKey = `${proxyName}__token`;
+const logger = createLogger(proxyName);
+
+async function login(loginUrl, username, password) {
+  const authResponse = await httpProxy(loginUrl, {
+    method: "POST",
+    body: JSON.stringify({ identity: username, secret: password }),
+    headers: {
+      "Content-Type": "application/json",
+    },
+  });
+
+  const status = authResponse[0];
+  const data = JSON.parse(Buffer.from(authResponse[2]).toString());
+
+  if (status === 200) {
+    cache.put(tokenCacheKey, data.token);
+  }
+
+  return [status, data.token ?? data];
+}
 
 export default async function npmProxyHandler(req, res) {
   const { group, service, endpoint } = req.query;
@@ -14,27 +41,54 @@ export default async function npmProxyHandler(req, res) {
 
     if (widget) {
       const url = new URL(formatApiCall(widgets[widget.type].api, { endpoint, ...widget }));
-
       const loginUrl = `${widget.url}/api/tokens`;
-      const body = { identity: widget.username, secret: widget.password };
 
-      const authResponse = await fetch(loginUrl, {
-        method: "POST",
-        body: JSON.stringify(body),
-        headers: {
-          "Content-Type": "application/json",
-        },
-      }).then((response) => response.json());
+      let status;
+      let contentType;
+      let data;
+      
+      let token = cache.get(tokenCacheKey);
+      if (!token) {
+        [status, token] = await login(loginUrl, widget.username, widget.password);
+        if (status !== 200) {
+          logger.debug(`HTTTP ${status} logging into npm api: ${data}`);
+          return res.status(status).send(data);
+        }
+      }
 
-      const apiResponse = await fetch(url, {
+      [status, contentType, data] = await httpProxy(url, {
         method: "GET",
         headers: {
           "Content-Type": "application/json",
-          Authorization: `Bearer ${authResponse.token}`,
+          Authorization: `Bearer ${token}`,
         },
-      }).then((response) => response.json());
+      });
 
-      return res.send(apiResponse);
+      if (status === 403) {
+        logger.debug(`HTTTP ${status} retrieving data from npm api, logging in and trying again.`);
+        cache.del(tokenCacheKey);
+        [status, token] = await login(loginUrl, widget.username, widget.password);
+
+        if (status !== 200) {
+          logger.debug(`HTTTP ${status} logging into npm api: ${data}`);
+          return res.status(status).send(data);
+        }
+
+        // eslint-disable-next-line no-unused-vars
+        [status, contentType, data] = await httpProxy(url, {
+          method: "GET",
+          headers: {
+            "Content-Type": "application/json",
+            Authorization: `Bearer ${token}`,
+          },
+        });
+      }
+
+      if (status !== 200) {
+        return res.status(status).send(data);
+      }
+
+      return res.send(data);
     }
   }