diff --git a/api/auth.go b/api/auth.go
index d6eae9b3d2246c543c306c514ff3e19f8c6be080..f96338aa2ae66b4d2b7599a17121be79dbbc1ea0 100644
--- a/api/auth.go
+++ b/api/auth.go
@@ -69,28 +69,38 @@ func (a *api) GetToken(w http.ResponseWriter, req *http.Request) {
 		w.WriteHeader(http.StatusUnauthorized)
 		return
 	}
-	num, ok := claims["num"].(float64)
+	numFloat, ok := claims["num"].(float64)
 	if !ok {
 		w.WriteHeader(http.StatusUnauthorized)
 		return
 	}
-	role, ok := claims["role"].(string)
-	if !ok {
-		w.WriteHeader(http.StatusUnauthorized)
+	num := int(numFloat)
+
+	member, err := a.db.GetMember(num)
+	if err != nil {
+		if errors.Is(err, db.ErrorNotFound) {
+			w.WriteHeader(http.StatusUnauthorized)
+		} else {
+			log.Printf("Can't get the member %d: %v", num, err)
+			w.WriteHeader(http.StatusInternalServerError)
+		}
 		return
 	}
+	role := member.Role
 
 	w.Header().Set("Content-Type", "application/json")
 	w.WriteHeader(http.StatusOK)
 
-	token, err := a.newToken(int(num), role, true)
+	_, expires := claims["exp"]
+	newToken, err := a.newToken(int(num), role, expires)
 	if err != nil {
 		log.Printf("Can't create a token: %v", err)
 		w.WriteHeader(http.StatusInternalServerError)
 		return
 	}
 	err = json.NewEncoder(w).Encode(map[string]interface{}{
-		"token": token,
+		"token": newToken,
+		"role":  role,
 	})
 	if err != nil {
 		log.Printf("Can't encode token: %v", err)
diff --git a/src/App.js b/src/App.js
index d576e9bfb2493a923811f9a391bea50acbea27d1..4fe08f600178f2b759f2db38456b8860aeef6e06 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,4 +1,4 @@
-import React, { useEffect, useState } from "react";
+import React, { useEffect } from "react";
 import { useStorageItem } from "@capacitor-community/react-hooks/storage";
 import Panel from "./Panel";
 import AuthContext from "./AuthContext";
@@ -9,27 +9,30 @@ function App() {
   const [num, setNum] = useStorageItem("num");
   const [role, setRole] = useStorageItem("role");
   const [token, setToken] = useStorageItem("token");
-  const [timerID, setTimerID] = useState(null);
 
   useEffect(() => {
-    if (!timerID) {
-      startRenew(token, setToken, setTimerID);
-    }
-    return () => stopRenew(timerID);
-  }, [token, setToken, timerID, setTimerID]);
+    const setTokenData = (data) => {
+      setToken(data.token);
+      setRole(data.role);
+    };
+
+    const timerID = window.setInterval(
+      () => renewToken(token, setTokenData),
+      60000 // every minute
+    );
+    return () => window.clearInterval(timerID);
+  }, [token, setToken, setRole]);
 
   const login = (newToken, member) => {
     setNum(member.num);
     setRole(member.role);
     setToken(newToken);
-    startRenew(newToken, setToken, setTimerID);
   };
 
   const logout = () => {
     setNum("");
     setRole("");
     setToken("");
-    stopRenew(timerID);
   };
 
   const value = { num, role, token };
@@ -55,7 +58,11 @@ function getClaims(token) {
   return JSON.parse(jsonPayload);
 }
 
-function renewToken(oldToken, setToken) {
+function renewToken(oldToken, setTokenData) {
+  if (!oldToken) {
+    return;
+  }
+
   fetch(url("/api/token"), {
     headers: { "x-authentication": oldToken },
   })
@@ -65,35 +72,16 @@ function renewToken(oldToken, setToken) {
       }
       return response.json();
     })
-    .then((data) => {
-      const token = data.token;
-      setToken(token);
-    })
+    .then(setTokenData)
     .catch((error) => {
       if (error instanceof ResponseError && error.response.status === 401) {
-        setToken("");
+        setTokenData({ token: "", role: "" });
       } else {
         console.log("Error renewing token: " + error.message);
       }
     });
 }
 
-function startRenew(token, setToken, setTimerID) {
-  if (token && getClaims(token)["exp"] !== undefined) {
-    const timerID = setInterval(
-      () => renewToken(token, setToken),
-      60000 // every minute
-    );
-    setTimerID(timerID);
-  }
-}
-
-function stopRenew(timerID) {
-  if (timerID) {
-    clearInterval(timerID);
-  }
-}
-
 function isLoggedIn(token) {
   if (!token) {
     return false;