diff --git a/src/server/api/authenticate.ts b/src/server/api/authenticate.ts
index bba4db4ace..6148ad33c5 100644
--- a/src/server/api/authenticate.ts
+++ b/src/server/api/authenticate.ts
@@ -2,11 +2,6 @@ import isNativeToken from './common/is-native-token';
 import { User } from '../../models/entities/user';
 import { Users, AccessTokens, Apps } from '../../models';
 import { AccessToken } from '../../models/entities/access-token';
-import { Cache } from '@/misc/cache';
-
-// TODO: TypeORMのカスタムキャッシュプロバイダを使っても良いかも
-// ref. https://github.com/typeorm/typeorm/blob/master/docs/caching.md
-const cache = new Cache<User>(1000 * 60 * 60);
 
 export class AuthenticationError extends Error {
 	constructor(message: string) {
@@ -21,11 +16,6 @@ export default async (token: string): Promise<[User | null | undefined, App | nu
 	}
 
 	if (isNativeToken(token)) {
-		const cached = cache.get(token);
-		if (cached) {
-			return [cached, null];
-		}
-
 		// Fetch user
 		const user = await Users
 			.findOne({ token });
@@ -34,11 +24,8 @@ export default async (token: string): Promise<[User | null | undefined, App | nu
 			throw new AuthenticationError('user not found');
 		}
 
-		cache.set(token, user);
-
 		return [user, null];
 	} else {
-		// TODO: cache
 		const accessToken = await AccessTokens.findOne({
 			where: [{
 				hash: token.toLowerCase() // app
diff --git a/src/server/api/endpoints/admin/suspend-user.ts b/src/server/api/endpoints/admin/suspend-user.ts
index 9f3c8eb6f8..912d6a5162 100644
--- a/src/server/api/endpoints/admin/suspend-user.ts
+++ b/src/server/api/endpoints/admin/suspend-user.ts
@@ -6,6 +6,7 @@ import { Users, Followings, Notifications } from '../../../../models';
 import { User } from '../../../../models/entities/user';
 import { insertModerationLog } from '../../../../services/insert-moderation-log';
 import { doPostSuspend } from '../../../../services/suspend-user';
+import { publishUserEvent } from '@/services/stream';
 
 export const meta = {
 	tags: ['admin'],
@@ -43,6 +44,11 @@ export default define(meta, async (ps, me) => {
 		targetId: user.id,
 	});
 
+	// Terminate streaming
+	if (Users.isLocalUser(user)) {
+		publishUserEvent(user.id, 'terminate', {});
+	}
+
 	(async () => {
 		await doPostSuspend(user).catch(e => {});
 		await unFollowAll(user).catch(e => {});
diff --git a/src/server/api/endpoints/i/delete-account.ts b/src/server/api/endpoints/i/delete-account.ts
index 0f04c4c92d..f5f0f32a4a 100644
--- a/src/server/api/endpoints/i/delete-account.ts
+++ b/src/server/api/endpoints/i/delete-account.ts
@@ -3,6 +3,7 @@ import * as bcrypt from 'bcryptjs';
 import define from '../../define';
 import { Users, UserProfiles } from '../../../../models';
 import { doPostSuspend } from '../../../../services/suspend-user';
+import { publishUserEvent } from '@/services/stream';
 
 export const meta = {
 	requireCredential: true as const,
@@ -30,4 +31,7 @@ export default define(meta, async (ps, user) => {
 	await doPostSuspend(user).catch(e => {});
 
 	await Users.delete(user.id);
+
+	// Terminate streaming
+	publishUserEvent(user.id, 'terminate', {});
 });
diff --git a/src/server/api/endpoints/i/regenerate-token.ts b/src/server/api/endpoints/i/regenerate-token.ts
index 3596e20197..3665ed0532 100644
--- a/src/server/api/endpoints/i/regenerate-token.ts
+++ b/src/server/api/endpoints/i/regenerate-token.ts
@@ -1,6 +1,6 @@
 import $ from 'cafy';
 import * as bcrypt from 'bcryptjs';
-import { publishMainStream } from '../../../../services/stream';
+import { publishMainStream, publishUserEvent } from '../../../../services/stream';
 import generateUserToken from '../../common/generate-native-user-token';
 import define from '../../define';
 import { Users, UserProfiles } from '../../../../models';
@@ -36,4 +36,9 @@ export default define(meta, async (ps, user) => {
 
 	// Publish event
 	publishMainStream(user.id, 'myTokenRegenerated');
+
+	// Terminate streaming
+	setTimeout(() => {
+		publishUserEvent(user.id, 'terminate', {});
+	}, 5000);
 });
diff --git a/src/server/api/endpoints/i/revoke-token.ts b/src/server/api/endpoints/i/revoke-token.ts
index d71a1bd135..d22d9ca693 100644
--- a/src/server/api/endpoints/i/revoke-token.ts
+++ b/src/server/api/endpoints/i/revoke-token.ts
@@ -2,6 +2,7 @@ import $ from 'cafy';
 import define from '../../define';
 import { AccessTokens } from '../../../../models';
 import { ID } from '@/misc/cafy-id';
+import { publishUserEvent } from '@/services/stream';
 
 export const meta = {
 	requireCredential: true as const,
@@ -19,6 +20,12 @@ export default define(meta, async (ps, user) => {
 	const token = await AccessTokens.findOne(ps.tokenId);
 
 	if (token) {
-		AccessTokens.delete(token.id);
+		await AccessTokens.delete({
+			id: ps.tokenId,
+			userId: user.id,
+		});
+
+		// Terminate streaming
+		publishUserEvent(user.id, 'terminate');
 	}
 });
diff --git a/src/server/api/private/signin.ts b/src/server/api/private/signin.ts
index 0a17b0bd02..c01c1f265a 100644
--- a/src/server/api/private/signin.ts
+++ b/src/server/api/private/signin.ts
@@ -46,6 +46,13 @@ export default async (ctx: Koa.Context) => {
 		return;
 	}
 
+	if (user.isSuspended) {
+		ctx.throw(403, {
+			error: 'user is suspended'
+		});
+		return;
+	}
+
 	const profile = await UserProfiles.findOneOrFail(user.id);
 
 	// Compare password
diff --git a/src/server/api/stream/index.ts b/src/server/api/stream/index.ts
index 647b890ff8..75d82cfe66 100644
--- a/src/server/api/stream/index.ts
+++ b/src/server/api/stream/index.ts
@@ -92,6 +92,11 @@ export default class Connection {
 				this.userProfile = body;
 				break;
 
+			case 'terminate':
+				this.wsConnection.close();
+				this.dispose();
+				break;
+
 			default:
 				break;
 		}
diff --git a/src/server/api/streaming.ts b/src/server/api/streaming.ts
index 57e8c90860..b431bc5ad3 100644
--- a/src/server/api/streaming.ts
+++ b/src/server/api/streaming.ts
@@ -22,6 +22,11 @@ module.exports = (server: http.Server) => {
 		// (現状はエラーがキャッチされておらずサーバーのログに流れて邪魔なので)
 		const [user, app] = await authenticate(q.i as string);
 
+		if (user?.isSuspended) {
+			request.reject(400);
+			return;
+		}
+
 		const connection = request.accept();
 
 		const ev = new EventEmitter();