diff --git a/config.toml.sample b/config.toml.sample
index 196ef5c3f4c2f9e46808cce2769e9fe187609cbd..cb965049a61ac6e5bd46386431dc6a59c1c9e173 100644
--- a/config.toml.sample
+++ b/config.toml.sample
@@ -37,6 +37,9 @@ bili_jct   = ''
 buvid3     = ''
 dedeuserid = ''
 
+# Refresh token, can be obtained from the main page by examing `window.localStorage.ac_time_value'.
+ac_time_value = ''
+
 [proxy]
 # If your server is located in China, videos and audo-only videos may likely break if not using proxy.
 video = true
diff --git a/refresher.py b/refresher.py
new file mode 100644
index 0000000000000000000000000000000000000000..5647770ccba3648031416c9fe2144c7d45a732bc
--- /dev/null
+++ b/refresher.py
@@ -0,0 +1,70 @@
+# Copyright (C) 2023 MikuInvidious Team
+# 
+# MikuInvidious is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 3 of
+# the License, or (at your option) any later version.
+# 
+# MikuInvidious is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with MikuInvidious. If not, see <http://www.gnu.org/licenses/>.
+
+import toml
+
+from bilibili_api import sync, Credential
+
+def discard_generated_data(fn):
+    with open(fn, 'r') as file:
+        lines = file.readlines()
+
+    index = None
+    for i, line in enumerate(lines):
+        if '## GENERATED DATA, DO NOT WRITE ANYTHING BELOW!!! ##\n' in line:
+            index = i
+            break
+
+    if index is not None:
+        with open(fn, 'w') as file:
+            file.writelines(lines[:index])
+            return True
+    else:
+        return False
+
+
+def renew_cookies(cred):
+    if sync(cred.check_refresh()):
+        sync(cred.refresh())
+        write_cookies(cred)
+        print('Cookies refreshed.')
+        return True
+    return False
+        
+def write_cookies(cred):
+    buf = '' if discard_generated_data('config.toml') else '\n\n'
+    buf += '## GENERATED DATA, DO NOT WRITE ANYTHING BELOW!!! ##\n'
+    buf += '[updatedcred]\n'
+    for k,v in cred.get_cookies().items():
+        buf += f'{k.lower()} = \'{v}\'\n'
+
+    with open('config.toml', 'a') as f:
+        f.write(buf)
+
+if __name__ == '__main__':
+    print('Trying to refresh the cookies...')
+    appconf = toml.load('config.toml')
+    credstore = appconf['updatedcred'] if 'updatedcred' in appconf else \
+        appconf['credential']
+    appcred = Credential(sessdata=credstore['sessdata'],
+                         bili_jct=credstore['bili_jct'],
+                         buvid3=credstore['buvid3'],
+                         dedeuserid=credstore['dedeuserid'],
+                         ac_time_value=credstore['ac_time_value'])
+
+    if renew_cookies(appcred):
+        print('Successfully refreshed the cookies.')
+    else:
+        print('Cookies are already up-to-date.')
diff --git a/shared.py b/shared.py
index f371519520ecfe467b40fb5c0c002c7b3e567dd9..64bb4f77070451823551e9db64e90cfdcdafeaa4 100644
--- a/shared.py
+++ b/shared.py
@@ -19,6 +19,8 @@ from aioflask import request, render_template, Flask
 from flask_caching import Cache
 from bilibili_api import Credential
 
+from refresher import renew_cookies
+
 try:
 	appconf = toml.load('config.toml')
 except FileNotFoundError:
@@ -36,10 +38,22 @@ appcache = Cache(app, config={'CACHE_TYPE': 'RedisCache'})
 
 # Initilize credentials for bilibili API.
 if appconf['credential']['use_cred']:
-    appcred = Credential(sessdata=appconf['credential']['sessdata'],
-                         bili_jct=appconf['credential']['bili_jct'],
-                         buvid3=appconf['credential']['buvid3'],
-                         dedeuserid=appconf['credential']['dedeuserid'])
+    credstore = appconf['updatedcred'] if 'updatedcred' in appconf else \
+        appconf['credential']
+    appcred = Credential(sessdata=credstore['sessdata'],
+                         bili_jct=credstore['bili_jct'],
+                         buvid3=credstore['buvid3'],
+                         dedeuserid=credstore['dedeuserid'],
+                         ac_time_value=credstore['ac_time_value'])
+
+    if renew_cookies(appcred):
+        appconf = toml.load('config.toml')
+        credstore = appconf['updatedcred']
+        appcred = Credential(sessdata=credstore['sessdata'],
+                             bili_jct=credstore['bili_jct'],
+                             buvid3=credstore['buvid3'],
+                             dedeuserid=credstore['dedeuserid'],
+                             ac_time_value=credstore['ac_time_value'])
 else:
     appcred = None