gmnon.cn-疯狂蹂躏欧美一区二区精品,欧美精品久久久久a,高清在线视频日韩欧美,日韩免费av一区二区

站長資訊網
最全最豐富的資訊網站

Node.js中怎么使用Redis?原來這么簡單!

Node中怎么使用Redis?下面本篇文章給大家介紹一下Node.js中使用Redis的方法,你會發現原來這么簡單,希望對大家有所幫助!

Node.js中怎么使用Redis?原來這么簡單!

node.js極速入門課程:進入學習

之前的文章中我們其實留了兩個可以用redis優化的地方:

  • 一個是我們的在做登錄時,通過JWT已經實現了服務端生成token以及驗證客戶端發送的token信息?!鞠嚓P教程推薦:nodejs視頻教程 、編程視頻】
  • 實現對文章點贊功能,采用的是將點贊數據直接寫入數據庫

JWT token 實現方式, 將基本信息直接放在token中,以便于分布式系統使用, 但是我們沒有設置有限期(這個是可以實現的),并且服務端無法主動讓token失效。 而Redis天然支持過期時間,也能實現讓服務端主動使token過期。

當然并不是說JWT token 不如 redis+token實現方案好, 具體看使用的場景,這里我們并不討論二者孰優孰劣,只是提供一種實現方案,讓大家知道如何實現。

1. 認識redis

對于前端的小伙伴來說,Redis可能相對比較陌生,首先認識一下

Redis是什么

Redis是一個開源(BSD許可)的,基于內存的數據結構存儲系統,它可以用作數據庫、緩存和消息中間件,是現在最受歡迎的 NoSQL 數據庫之一。

其具備如下特性:

  • 速度快
    • 單節點讀110000次/s,寫81000次/s
    • 基于內存運行,性能高效
    • 用 C 語言實現,離操作系統更近
  • 持久化
    • 數據的更新將異步地保存到硬盤(RDB 和 AOF
  • 多種數據結構
    • 不僅僅支持簡單的 key-value 類型數據
    • 還支持:字符串、hash、列表、集合、有序集合
  • 支持多種編程語言等等

Redis 典型使用場景

緩存

緩存可以說是Redis最常用的功能之一了, 合理的緩存不僅可以加快訪問的速度,也可以減少后端數據庫的壓力。

排行系統

利用Redis的列表和有序集合的特點,可以制作排行榜系統,而排行榜系統目前在商城類、新聞類、博客類等等,都是比不可缺的。

計數器應用

計數器的應用基本和排行榜系統一樣,都是多數網站的普遍需求,如視頻網站的播放計數,電商網站的瀏覽數等等,但這些數量一般比較龐大,如果存到關系型數據庫,對MySQL或者其他關系型數據庫的挑戰還是很大的,而Redis基本可以說是天然支持計數器應用。

(視頻直播)消息彈幕

直播間的在線用戶列表,禮物排行榜,彈幕消息等信息,都適合使用Redis中的SortedSet結構進行存儲。

例如彈幕消息,可使用ZREVRANGEBYSCORE排序返回,在Redis5.0中,新增了zpopmaxzpopmin命令,更加方便消息處理。

Redis的應用場景遠不止這些,Redis對傳統磁盤數據庫是一個重要的補充,是支持高并發訪問的互聯網應用必不可少的基礎服務之一。

紙上談兵終覺淺,必須實戰一波~

Redis的安裝和簡單使用,我這里就不一一介紹了,這里貼上我之前寫的兩篇文章:

  • Redis 安裝
  • Redis入門篇-基礎使用

可以快速的安裝、了解Redis數據類型以及常用的命令。

可視化客戶端

在Windows下使用 RedisClient, 在mac下可以使用Redis Desktop Manager

RedisClient下載鏈接:https://github.com/caoxinyu/RedisClient

下載后直接雙擊redisclient-win32.x86.2.0.exe文件運行即可

Node.js中怎么使用Redis?原來這么簡單!

啟動后, 點擊server -> add

Node.js中怎么使用Redis?原來這么簡單!

連接后就可以看到總體情況了:

Node.js中怎么使用Redis?原來這么簡單!

與SQL型數據不同,redis沒有提供新建數據庫的操作,因為它自帶了16(0-15)個數據庫(默認使用0庫)。在同一個庫中,key是唯一存在的、不允許重復的,它就像一把“密鑰”,只能打開一把“鎖”。鍵值存儲的本質就是使用key來標識value,當想要檢索value時,必須使用與value對應的key進行查找.

Redis認識作為文章前置條件,到這里及結束了, 接下來進入正題~

本文主要使用Redis實現緩存功能。

2. 在Nest.js中使用

版本情況:

版本
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配置文件中:

Node.js中怎么使用Redis?原來這么簡單!

使用Nest官方推薦的方法,只需要簡單的3個步驟:

1、引入依賴文件

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、創建module文件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 {}
登錄后復制

  • CacheModuleregisterAsync方法采用 Redis Store 配置進行通信
  • store 屬性值redisStore ,表示'cache-manager-redis-store' 庫
  • isGlobal 屬性設置為true 來將其聲明為全局模塊,當我們將RedisCacheModuleAppModule中導入時, 其他模塊就可以直接使用,不需要再次導入
  • 由于Redis 信息寫在配置文件中,所以采用registerAsync()方法來處理異步數據,如果是靜態數據, 可以使用register

3、新建redis-cache.service.ts文件, 在service實現緩存的讀寫

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即可。

調整 token 簽發及驗證流程

我們借助redis來實現token過期處理、token自動續期、以及用戶唯一登錄。

  • 過期處理:把用戶信息及token放進redis,并設置過期時間
  • token自動續期:token的過期時間為30分鐘,如果在這30分鐘內沒有操作,則重新登錄,如果30分鐘內有操作,就給token自動續一個新的時間,防止使用時掉線。
  • 戶唯一登錄:相同的賬號,不同電腦登錄,先登錄的用戶會被后登錄的擠下線

token 過期處理

在登錄時,將jwt生成的token,存入redis,并設置有效期為30分鐘。存入redis的key由用戶信息組成, value是token值。

// 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 };  }
登錄后復制

在驗證token時, 從redis中取token,如果取不到token,可能是token已過期。

// 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;   } }
登錄后復制

用戶唯一登錄

當用戶登錄時,每次簽發的新的token,會覆蓋之前的token, 判斷redis中的token與請求傳入的token是否相同, 不相同時, 可能是其他地方已登錄, 提示token錯誤。

// 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;   }
登錄后復制

token自動續期

實現方案有多種,可以后臺jwt生成access_token(jwt有效期30分鐘)和refresh_token, refresh_token有效期比access_token有效期長,客戶端緩存此兩種token, 當access_token過期時, 客戶端再攜帶refresh_token獲取新的access_token。 這種方案需要接口調用的開發人員配合。

我這里主要介紹一下,純后端實現的token自動續期

實現流程:

  • ①:jwt生成token時,有效期設置為用不過期
  • ②:redis 緩存token時設置有效期30分鐘
  • ③:用戶攜帶token請求時, 如果key存在,且value相同, 則重新設置有效期為30分鐘

設置jwt生成的token, 用不過期, 這部分代碼是在auth.module.ts文件中, 不了解的可以看文章 Nest.js 實戰系列第二篇-實現注冊、掃碼登陸、jwt認證

// auth.module.ts const jwtModule = JwtModule.registerAsync({   inject: [ConfigService],   useFactory: async (configService: ConfigService) => {     return {       secret: configService.get('SECRET', 'test123456'), -     signOptions: { expiresIn: '4h' },  // 取消有效期設置     };   }, });
登錄后復制

然后再token認證通過后,重新設置過期時間, 因為使用的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中實現token過期處理、token自動續期、以及用戶唯一登錄都完成了, 退出登錄時移除token比較簡單就不在這里一一上代碼了。

在Nest中除了使用官方推薦的這種方式外, 還可以使用nestjs-redis來實現,如果你存token時, 希望存hash結構,使用cache-manager-redis-store時,會發現沒有提供hash值存取放方法(需要花點心思去發現)。

注意:如果使用nest-redis來實現redis緩存, 在Nest.js 8 版本下會報錯, 小伙伴們可以使用@chenjm/nestjs-redis 來代替, 或者參考 issue上的解決方案:Nest 8 + redis bug。

總結

源碼地址:https://github.com/koala-coding/nest-blog

贊(0)
分享到: 更多 (0)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
gmnon.cn-疯狂蹂躏欧美一区二区精品,欧美精品久久久久a,高清在线视频日韩欧美,日韩免费av一区二区
久久久久久久久久久久久久久国产| 午夜视频在线瓜伦| 五月花丁香婷婷| 91淫黄看大片| 亚洲男人天堂色| www.se五月| 九九九九九九九九| 特级黄色录像片| 国产成人免费高清视频| 中文字幕av久久| 日本福利视频在线观看| 国产a级黄色大片| 国产二区视频在线| 日日鲁鲁鲁夜夜爽爽狠狠视频97| 蜜桃传媒一区二区三区| 欧美 国产 小说 另类| 日韩毛片在线免费看| 嫩草影院国产精品| 三日本三级少妇三级99| 青青草综合在线| 精品国产免费av| 天天干天天干天天干天天干天天干| 蜜臀av免费观看| 三年中文高清在线观看第6集| 永久免费黄色片| 日本www在线视频| 美女黄色片视频| 久久久久久久香蕉| 日韩精品―中文字幕| 天堂中文视频在线| 老司机午夜网站| 国产一区视频免费观看| 免费不卡av网站| 97成人在线观看视频| 日本高清免费观看| 成年人黄色片视频| 天天想你在线观看完整版电影免费| 999在线观看视频| 亚洲天堂网2018| 日本www在线播放| 国产1区2区3区中文字幕| 成人一区二区三| 日本xxxxxxxxxx75| 特级黄色片视频| 中文字幕天天干| 18禁免费观看网站| 国产高清不卡无码视频| 爱爱爱爱免费视频| 欧美日韩亚洲一| 国产性生活免费视频| 污污网站免费观看| 国产xxxxx视频| 91免费黄视频| 免费拍拍拍网站| 热这里只有精品| 四虎成人在线播放| 岛国毛片在线播放| 好男人www社区| 黑森林福利视频导航| 国产主播自拍av| 国产在线视频在线| 成人高清dvd| 免费一级淫片aaa片毛片a级| 五月六月丁香婷婷| 亚洲一二三av| 亚洲欧美一二三| 中文字幕一区二区三区四区五区人| 自拍偷拍一区二区三区四区| 午夜欧美福利视频| 男人添女人下面免费视频| 国产一区视频免费观看| 久久精品免费网站| 黄色三级视频在线| 日韩一区二区三区久久| 天天干天天操天天玩| 天天干天天玩天天操| 亚洲综合20p| 日本高清视频免费在线观看| 一级黄色免费在线观看| 日韩精品视频网址| 日韩精品福利片午夜免费观看| 男人的天堂视频在线| 女人被男人躁得好爽免费视频| 精品成在人线av无码免费看| 成人免费观看cn| 9久久婷婷国产综合精品性色| 国产精品v日韩精品v在线观看| 亚洲欧美日韩网站| wwwwww欧美| 欧美精品无码一区二区三区| 最新天堂中文在线| 成人污网站在线观看| 男人靠女人免费视频网站| 日本免费观看网站| 久久久无码中文字幕久...| a天堂资源在线观看| 欧美精品第三页| 欧美日韩视频免费在线观看| 麻豆tv在线播放| 亚洲免费黄色网| 中文字幕超清在线免费观看| 日韩伦理在线免费观看| 国产精品久久久毛片| 无码毛片aaa在线| 妞干网在线免费视频| 手机在线观看日韩av| 日日摸日日碰夜夜爽无码| 熟女性饥渴一区二区三区| av在线观看地址| 丝袜老师办公室里做好紧好爽| 黄色av免费在线播放| 成人午夜精品久久久久久久蜜臀| 校园春色 亚洲色图| 国产美女永久无遮挡| 三上悠亚av一区二区三区| 2019日韩中文字幕mv| 国产精品区在线| 2018国产在线| 亚洲国产精品影视| 午夜激情在线观看视频| 欧美视频在线第一页| 性生生活大片免费看视频| 国产无套粉嫩白浆内谢的出处| 国产黄色激情视频| 亚洲综合婷婷久久| 91视频免费版污| 成年人免费在线播放| 欧美黑人经典片免费观看| 欧洲美女和动交zoz0z| 天天干天天综合| 黄色片视频在线播放| 欧美日韩在线中文| 日本日本19xxxⅹhd乱影响| 亚洲啊啊啊啊啊| 四虎免费在线观看视频| 操人视频免费看| 日本xxx免费| 一本二本三本亚洲码 | 999这里有精品| 免费毛片小视频| 男人天堂1024| 男人天堂999| av7777777| 男人用嘴添女人下身免费视频| 亚洲综合激情五月| 国产精品久久久影院| 懂色av粉嫩av蜜臀av| 国产免费xxx| 日韩黄色片在线| 青草视频在线观看视频| 欧美久久久久久久久久久久久久| 国产又粗又长又爽视频| 97免费视频观看| 国产淫片av片久久久久久| 五月婷婷丁香综合网| 中文字幕国产高清| 国产精品国三级国产av| 日韩在线一级片| 黄色小视频免费网站| 国产在线无码精品| 虎白女粉嫩尤物福利视频| 污片在线免费看| 亚洲天堂第一区| 日本免费黄视频| 日本国产一级片| www.av91| 欧美特级aaa| 亚洲av首页在线| 亚洲精品无码久久久久久| av亚洲天堂网| av免费观看大全| 亚洲天堂av免费在线观看| 久久婷婷五月综合色国产香蕉| 思思久久精品视频| 缅甸午夜性猛交xxxx| 国内av免费观看| 黄色片一级视频| 今天免费高清在线观看国语| www日韩在线观看| 国产在线观看欧美| 伊人免费视频二| 欧美综合在线观看视频| 69精品丰满人妻无码视频a片| 爱情岛论坛成人| 高清无码一区二区在线观看吞精| 人妻少妇精品无码专区二区| 手机在线免费毛片| 欧美黄色一级片视频| 精品无码国模私拍视频| 干日本少妇视频| 少妇熟女一区二区| 一级黄色片国产| 日本中文字幕精品—区二区| 丰满人妻中伦妇伦精品app| 青青在线免费视频| xxx中文字幕| 夜夜爽久久精品91| 特级西西人体www高清大胆| 手机免费av片| 乌克兰美女av|