Node で Redis を使用するにはどうすればよいですか?次の記事では、Node.js で Redis を使用する方法を紹介します。とても簡単であることがわかります。お役に立てば幸いです。
前の記事では、実際には redis
で最適化できる 2 つの場所を残しました:
- 1 つは私たちですログイン時に、サーバーは
token
の生成と、クライアントから JWT
を通じて送信された token
情報の検証を実装しています。 [関連チュートリアルの推奨事項: nodejs ビデオ チュートリアル 、プログラミング ビデオ ]
- は、データベースに直接いいねデータを書き込むことで、記事にいいねをする機能を実装します
JWTトークン
実装方法は、分散システムの利用を容易にするため、token
に直接基本情報を入れる方式ですが、期限は設けておりません(可能です)実装されています)、サーバーは token
を積極的に無効にすることができません。 Redis は有効期限を当然サポートしており、サーバーが token
をアクティブに期限切れにすることもできます。
もちろん、これは JWT トークンが Redis トークンの実装ほど優れていないという意味ではありません。それは使用シナリオによって異なります。ここではどちらが優れているかについては説明しませんが、実装ソリューションを提供するだけです。誰もがそれを実装する方法を知っています。
#1. redis について知る
フロントエンドの友人にとって、Redis は比較的馴染みのないものかもしれません。 #Redis とは何ですか?
#Redis は、オープン ソース (BSD ライセンス) のメモリベースのデータ構造ストレージ システムであり、データベース、キャッシュ、メッセージ ミドルウェアとして使用できます。現在最も人気のある NoSQL データベース。 これには次の特徴があります:
高速速度
単一ノードは 110,000 回/秒の読み取りと 81,000 回/秒の書き込みが可能です
- メモリに基づいて実行され、高性能
- C 言語で実装され、オペレーティング システムに近い
-
- 永続性
データ更新は非同期で保存されます。ハードディスク (RDB および AOF
##複数のデータ構造 - #単純なキー値型データだけでなく、文字列、ハッシュ、リストもサポート、セット、順序付きセット
- #複数のプログラミング言語などをサポート ##キャッシュ
- キャッシュは Redis で最もよく使用される機能の 1 つと言えます。合理的なキャッシュにより、アクセスが高速化されるだけでなく、バックエンド データベースへの負荷も軽減されます。
ランキング システム
Redis リストと順序付きコレクションの特性を利用して、ランキング システムを作成できます。ランキング システムは現在、ショッピング モール、ニュース、ブログ、
カウンター アプリケーション
カウンターのアプリケーションは基本的にランキング システムと同じであり、これはほとんどの Web サイトに共通の要件です。動画 Web サイトの再生回数、電子商取引 Web サイトの再生回数などですが、これらの数値は一般に比較的大きいため、リレーショナル データベースに保存した場合でも、MySQL やその他のリレーショナル データベースにとって大きな課題となります。 Redis は基本的にカウンター アプリケーションを自然にサポートしていると言えます。ライブ ブロードキャスト ルームはすべて、Redis の SortedSet 構造を使用したストレージに適しています。たとえば、集中砲火メッセージは
ZREVRANGEBYSCORE
を使用して並べ替えて返すことができます。Redis5.0 では、新しい
zpopmax
および zpopmin コマンドが追加されました。メッセージ処理がさらに便利になりました。
Redis のアプリケーション シナリオはこれらをはるかに超えています。Redis は、従来のディスク データベースの重要な補足であり、大量の同時アクセスをサポートするインターネット アプリケーションにとって不可欠な基本サービスの 1 つです。
机上で話すのは結局のところ浅いので、練習する必要があります~Redis のインストールと簡単な使用法については紹介しません。ここでは、私が以前に書いた 2 つの記事を紹介します:
Redis のインストール
#Redis の使用を開始する - 基本的な使用
Redis のデータ型と一般的に使用されるコマンドを簡単にインストールして理解できます。
##ビジュアル クライアント
RedisClient
を使用します。 Windows では - Redis Desktop Manager##、Mac では #RedisClient のダウンロード リンク: https://github.com/caoxinyu/RedisClient
- ダウンロード後、# をダブルクリックします。実行する ##redisclient-win32.x86.2.0.exe ファイル
が起動したら、「
server -> add##」をクリックします。
#
接続後、全体の状況を確認できます。
SQL 型のデータとは異なり、redis には新しいデータベースを作成する操作はありません。 16 (0 ~ 15) データベース (デフォルトでは 0 データベースが使用されます)。キーは同じライブラリ内に唯一存在し、重複することはできません。「鍵」のようなもので、「錠」は 1 つしか開けられません。 Key-Value ストレージの本質は、キーを使用して値を識別することです。値を取得する場合は、値に対応するキーを使用して検索する必要があります。
Redis の認識は、この記事の前提条件です。これは、本題に入ります~
この記事では主に Redis を使用してキャッシュ機能を実装します。
#2. Nest.js バージョンで
# を使用する:
#Library
Version |
|
Nest.js
V8.1.2 |
|
プロジェクトは、Nest.js 8.x
バージョンに基づいており、Nest.js 9.x
バージョンとは異なります。次の記事では、これらのバージョン間の違いを具体的に整理しています。 V8
から V9
にアップグレードする手順と方法については、ここでは説明しません。
まず、Nest.js プロジェクトで Redis を接続します。Redis の接続に必要なパラメーター:
REDIS_HOST:Redis 域名
REDIS_PORT:Redis 端口号
REDIS_DB: Redis 数据库
REDIS_PASSPORT:Redis 设置的密码
ログイン後にコピー
パラメーターを .env
と .env に書き込みます。 .prod
設定ファイル内:
Nest によって公式に推奨されている方法を使用します。必要な手順は 3 つの簡単な手順だけです:
1. 依存関係を導入します。 files
npm install cache-manager --save
npm install cache-manager-redis-store --save
npm install @types/cache-manager -D
ログイン後にコピー
Nest
さまざまなキャッシュ ストレージに統合された API を提供します。組み込みのデータ ストレージはメモリ内にありますが、cache-manager
を使用して他のソリューションを使用してください。たとえば、キャッシュには Redis
を使用します。
キャッシュを有効にするには、ConfigModule
をインポートし、register()
または registerAsync()
を呼び出して応答構成パラメーターを渡します。
2. モジュール ファイル src/db/redis-cache.module.ts
を作成し、次のように実装します:
import { ConfigModule, ConfigService } from '@nestjs/config';
import { RedisCacheService } from './redis-cache.service';
import { CacheModule, Module, Global } from '@nestjs/common';
import * as redisStore from 'cache-manager-redis-store';
@Module({
imports: [
CacheModule.registerAsync({
isGlobal: true,
imports: [ConfigModule],
inject: [ConfigService],
useFactory: async (configService: ConfigService) => {
return {
store: redisStore,
host: configService.get('REDIS_HOST'),
port: configService.get('REDIS_PORT'),
db: 0, //目标库,
auth_pass: configService.get('REDIS_PASSPORT') // 密码,没有可以不写
};
},
}),
],
providers: [RedisCacheService],
exports: [RedisCacheService],
})
export class RedisCacheModule {}
ログイン後にコピー
CacheModule
registerAsync
メソッドは Redis ストア構成を使用して store
'cache-manager-redis-store' ライブラリを示す属性値 redisStore
##AppModule- に
RedisCacheModule
をインポートするとき、
#isGlobal プロパティは
true に設定され、グローバル モジュールとして宣言されます。
設定ファイルにRedisの情報が記述されているため、非同期データの処理には- registerAsync()
メソッドを使用します静的データの場合は、
register
3 を使用して、新しい redis-cache.service.ts ファイルを作成し、キャッシュの読み取りおよび書き込み
import { Injectable, Inject, CACHE_MANAGER } from '@nestjs/common';
import { Cache } from 'cache-manager';
@Injectable()
export class RedisCacheService {
constructor(
@Inject(CACHE_MANAGER)
private cacheManager: Cache,
) {}
cacheSet(key: string, value: string, ttl: number) {
this.cacheManager.set(key, value, { ttl }, (err) => {
if (err) throw err;
});
}
async cacheGet(key: string): Promise<any> {
return this.cacheManager.get(key);
}
}
ログイン後にコピー
# を実装できます。サービス内の ## 接続 ダウンして、app.module.ts に RedisCacheModule
をインポートします。
トークンの発行と検証プロセスを調整するRedis を使用して、トークンの有効期限処理、自動トークン更新、および一意のユーザー ログインを実装します。
有効期限処理: ユーザー情報とトークンを redis に配置し、有効期限を設定します。 トークンの自動更新: トークンの有効期限は 30 分です (30 分以内の場合)。操作が無い場合は、再度ログインしてください。使用中の切断を防ぐため、30分以内に操作があった場合、トークンは自動的に更新されます。 各ユーザーに固有のログイン: 同じアカウント、別のコンピューターへのログイン、最初にログインしたユーザーは、後でログインしたユーザーによってオフラインにプッシュされます
トークンの有効期限の処理ログイン後 このとき、jwtで生成したトークンをredisに格納し、有効期限を30分に設定します。 redis に格納される key はユーザー情報で構成され、value はトークン値です。 // auth.service.ts
async login(user: Partial<User>) {
const token = this.createToken({
id: user.id,
username: user.username,
role: user.role,
});
+ await this.redisCacheService.cacheSet(
+ `${user.id}&${user.username}&${user.role}`,
+ token,
+ 1800,
+ );
return { token };
}
ログイン後にコピー
トークンを検証する場合は、redis からトークンを取得してください。トークンが取得できない場合は、トークンの有効期限が切れている可能性があります。 // jwt.strategy.ts
+ import { RedisCacheService } from './../core/db/redis-cache.service';
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(
@InjectRepository(User)
private readonly userRepository: Repository<User>,
private readonly authService: AuthService,
private readonly configService: ConfigService,
+ private readonly redisCacheService: RedisCacheService,
) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: configService.get('SECRET'),
+ passReqToCallback: true,
} as StrategyOptions);
}
async validate(req, user: User) {
+ const token = ExtractJwt.fromAuthHeaderAsBearerToken()(req);
+ const cacheToken = await this.redisCacheService.cacheGet(
+ `${user.id}&${user.username}&${user.role}`,
+ );
+ if (!cacheToken) {
+ throw new UnauthorizedException('token 已过期');
+ }
const existUser = await this.authService.getUser(user);
if (!existUser) {
throw new UnauthorizedException('token不正确');
}
return existUser;
}
}
ログイン後にコピー
ユーザーのみのログイン
ユーザーがログインすると、発行された新しいトークンが以前のトークンを上書きし、redis 内のトークンと受信リクエストがトークンであるかどうかを判断します。同じでしょうか?そうでない場合は、ユーザーが別の場所でログインしており、トークン エラーが表示されている可能性があります。 // jwt.strategy.ts
async validate(req, user: User) {
const token = ExtractJwt.fromAuthHeaderAsBearerToken()(req);
const cacheToken = await this.redisCacheService.cacheGet(
`${user.id}&${user.username}&${user.role}`,
);
if (!cacheToken) {
throw new UnauthorizedException('token 已过期');
}
+ if (token != cacheToken) {
+ throw new UnauthorizedException('token不正确');
+ }
const existUser = await this.authService.getUser(user);
if (!existUser) {
throw new UnauthorizedException('token不正确');
}
return existUser;
}
ログイン後にコピー
トークンの自動更新
多くの実装ソリューションがあり、access_token (jwt は 30 分間有効) と
を生成できます。背景 jwt refresh_token、
refresh_token の有効期間は
access_token よりも長くなります。クライアントはこれら 2 つのトークンをキャッシュします。
access_token の有効期限が切れると、クライアントは ## を保持します。 # 再度、refresh_token
新しい access_token
を取得します。この解決策には、インターフェイス呼び出しの開発者の協力が必要です。
ここではピュアバックエンドで実装したトークンの自動更新を中心に紹介します
実装プロセス:
①: jwtがトークンを生成する際の有効期限は [有効期限なし] に設定されています。- ②: Redis がトークンをキャッシュするときに有効期間を 30 分に設定します。
- ③: ユーザーがトークン リクエストを送信するとき、キーが存在し、値が同様に、有効期間は 30 分にリセットされます
jwt によって生成されたトークンが期限切れにならないように設定します。コードのこの部分は
auth.module.ts## にあります。 # ファイル。理解できない場合は、記事 Nest.js 実践シリーズ パート 2 - 登録、スキャン コード ログイン、JWT 認証の実装
// auth.module.ts
const jwtModule = JwtModule.registerAsync({
inject: [ConfigService],
useFactory: async (configService: ConfigService) => {
return {
secret: configService.get('SECRET', 'test123456'),
- signOptions: { expiresIn: '4h' }, // 取消有效期设置
};
},
});
ログイン後にコピー
を読んでから、使用されている cache-manager が直接更新されていないため、トークン認証が通過した後の有効期限です。 有効期間メソッドは、リセットすることで実装されます: // jwt.strategy.ts
async validate(req, user: User) {
const token = ExtractJwt.fromAuthHeaderAsBearerToken()(req);
const cacheToken = await this.redisCacheService.cacheGet(
`${user.id}&${user.username}&${user.role}`,
);
if (!cacheToken) {
throw new UnauthorizedException('token 已过期');
}
if (token != cacheToken) {
throw new UnauthorizedException('token不正确');
}
const existUser = await this.authService.getUser(user);
if (!existUser) {
throw new UnauthorizedException('token不正确');
}
+ this.redisCacheService.cacheSet(
+ `${user.id}&${user.username}&${user.role}`,
+ token,
+ 1800,
+ );
return existUser;
}
ログイン後にコピー
この時点で、トークンの有効期限処理は、トークンの自動更新、ユーザーのみのログインはNestで完了します。ログアウト時にトークンを削除する方が簡単です。コードを1つずつ示します。
Nest で公式に推奨されている方法を使用することに加えて、nestjs-redis
を使用して実装することもできます。トークンを保存したい場合は、 を保存します。 cache-manager-redis-store
を使用すると、hash
値の保存および取得メソッドがないことがわかります (これを見つけるには多少の労力がかかります) )。 <blockquote><p>注: <code>nest-redis
を使用して Redis キャッシュを実装すると、Nest.js 8 バージョンでエラーが報告されます。友人は @chenjm/nestjs-redis# を使用できます。 # # 代わりに、または問題の解決策を参照してください:
Nest 8 redis bug。
概要
ソースコードのアドレス: https://github.com/koala-coding/nest-blogその他のプログラミング関連知識については、プログラミング教育をご覧ください。 !
以上がNode.js で Redis を使用するにはどうすればよいですか?それはとても簡単だということがわかりました。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。