diff --git a/client/src/adapters/auth.ts b/client/src/adapters/auth.ts
index 5dbde550cd0b01b26df3a6c66138459de4641edc..48198a66d066bf82d844922c4e9f870d20a4e540 100644
--- a/client/src/adapters/auth.ts
+++ b/client/src/adapters/auth.ts
@@ -37,7 +37,7 @@ async function extendAccessToken() {
             if (response.ok) {
                 const json = await response.json();
                 setToken(json.token);
-            } else if (response.status === 403) {
+            } else {
                 clearToken();
             }
         } catch(e) {
diff --git a/client/src/config.ts b/client/src/config.ts
index 38c8d39c67e67d3c160d59ad6e398406abdeb632..f7959fd9c4c74fbb54ca2116f8e95c33efdcde17 100644
--- a/client/src/config.ts
+++ b/client/src/config.ts
@@ -1,3 +1,9 @@
 
-export const apiRoot = `${window.location.origin}/v1`;
+export let apiRoot: string;
+
+if (process.env.NODE_ENV === 'production') {
+    apiRoot = `${window.location.origin}/v1`;
+} else {
+    apiRoot = `http://localhost:8000/v1`;
+}
 
diff --git a/server/src/config.ts b/server/src/config.ts
index 26fd98f447e9cad3fdbf8db5d0fd6c5346e72246..0e758a19ab66213d1c2dcf892ac34c82b22d2270 100644
--- a/server/src/config.ts
+++ b/server/src/config.ts
@@ -6,6 +6,7 @@ export const port = env.PORT ?? 8000;
 export const keys = {
     private: './keys/cert.key',
     public: './keys/cert.pem',
+    secret: 'SECRET',
 };
 
 export const allowedOrigins = [ "*" ];
diff --git a/server/src/keys.ts b/server/src/keys.ts
index 96e0edfb50554afd9e5333c1dfafd2dd19e66ee3..0c28f6b51e3190b2318398d6bbcfd7f37e660ee0 100644
--- a/server/src/keys.ts
+++ b/server/src/keys.ts
@@ -3,6 +3,25 @@ import { readFileBuffer } from './util';
 import { env } from 'process';
 import { keys } from './config';
 
+let hasKeys: boolean | null = null;
+
+export async function usePublicAndPrivate(): Promise<boolean> {
+    if (hasKeys === null) {
+        try {
+            await getPrivateKey();
+            await getPublicKey();
+            hasKeys = true;
+        } catch(e) {
+            hasKeys = false;
+        }
+    }
+    return hasKeys;
+}
+
+export function getSecret(): string {
+    return keys.secret;
+}
+
 let privateKey: string;
 
 export async function getPrivateKey(): Promise<string> {
diff --git a/server/src/knexconfig.ts b/server/src/knexconfig.ts
index 7f5a5030b168e6ef2bc5c57aac571a7073005cbe..66f12382c2c193d850168b9caeeded6e57a46b0d 100644
--- a/server/src/knexconfig.ts
+++ b/server/src/knexconfig.ts
@@ -3,7 +3,7 @@ import { env } from 'process';
 import { join } from 'path';
 import { parse } from 'pg-connection-string';
 
-const pgconfig: any = parse(env.DATABASE_URL ?? '');
+const pgconfig: any = parse(env.DATABASE_URL ?? 'postgresql://postgres@localhost/ryoko');
 
 export default {
     development: {
diff --git a/server/src/v1/auth.ts b/server/src/v1/auth.ts
index eb667d293338fd973919b0371344f54cd757e519..01418d90734901ade0d755566899cbe3306312fb 100644
--- a/server/src/v1/auth.ts
+++ b/server/src/v1/auth.ts
@@ -6,7 +6,7 @@ import { sign, verify } from 'jsonwebtoken';
 
 import database from '../database';
 import { isOfType, asyncify } from '../util';
-import { getPublicKey, getPrivateKey } from '../keys';
+import { getPublicKey, getPrivateKey, getSecret, usePublicAndPrivate } from '../keys';
 
 const auth = express();
 
@@ -31,9 +31,13 @@ export async function tokenVerification(req: Request, _res: Response, next: Next
     if (token) {
         delete req.body.token;
         try {
-            const decoded = await asyncify(verify, token, await getPublicKey(), { algorithms: ["ES384"] });
-            if (isOfType<Token>(decoded, [['id', 'string'], ['type', 'string']]) && decoded.type === authTokenType) {
-                req.body.token = decoded;
+            if (await usePublicAndPrivate()) {
+                const decoded = await asyncify(verify, token, await getPublicKey(), { algorithms: ["ES384"] });
+                if (isOfType<Token>(decoded, [['id', 'string'], ['type', 'string']]) && decoded.type === authTokenType) {
+                    req.body.token = decoded;
+                }
+            } else {
+                return asyncify(verify, token, getSecret(), { algorithms: ["HS384"] });
             }
         } catch (err) { /* Token has already been deleted */ }
         next();
@@ -58,7 +62,11 @@ async function generateAuthToken(id: string) {
         id: id,
         type: authTokenType,
     };
-    return asyncify(sign, token, await getPrivateKey(), { algorithm: "ES384", expiresIn: 60 * 60 });
+    if (await usePublicAndPrivate()) {
+        return asyncify(sign, token, await getPrivateKey(), { algorithm: "ES384", expiresIn: 60 * 60 });
+    } else {
+        return asyncify(sign, token, getSecret(), { algorithm: "HS384", expiresIn: 60 * 60 });
+    }
 }
 
 interface RegisterBody {