Nest.js學習之路(24)-Http Bearer Token保護API End Point-使用Passport

這一章主要講Passport,他提供基本的bearer、jwt及oauth第三方登入,只要安裝不同的Strategy,官網上Strategies頁面也可以搜尋

如:

建立module建議用@nest/cli會建立資料夾、檔案及自動import AppModule

在feature文件下新建auth文件夾,然后在在auth文件下,用@nest/cli建立module

nest g module moduleName

流程大致如下:

  1. 建立AuthModule
    • 用來統(tǒng)一存放關于Auth的component
  2. 建立AuthService
    • 寫驗證使用者的邏輯、issue token等
  3. 新增UserService驗證方法
  4. 建立HttpStrategy
    • 告訴Passort Module怎么驗證使用者,通常是呼叫auth service里面的方法
  5. 在AuthModule下的provider注冊AuthService及HttpStrategy
  6. import UserModule
    • 需要存取使用者資訊,驗證帳號密碼等
  7. 到要保護的Controller或handler method套上@UseGuards()
  8. 測試

先用已知bearer token來理解Passport的運作,

安裝相關套件

yarn add @nestjs/passport passport passport-http-bearer

新增AuthModule

import { Module } from '@nestjs/common';

@Module({})
export class AuthModule {}

新增AuthService

在auth資料夾下新增auth.service.ts

import { Injectable } from '@nestjs/common';
import { UserService } from 'feature/user/user.service';

@Injectable()
export class AuthService {
  constructor(
      // 注入UsersService,所以需要import UsersModule
      // 底下的provider才能被注入
      private readonly usersService: UserService,
  ) {}

  async validateUser(token: string): Promise<any> {
    // 先假定token已知,由userService回傳使用者資料
    // 如果token不正確則回傳null
    return await this.usersService.findOneByToken(token);
  }
}

新增使用者驗證方法

修改user.service.ts

...
async findOneByToken(token){
    // 假定token為geekjc
    if (token === 'geekjc')
      return this.getUserById(8);
    else
      return null;
}
...

新增HttpStrategy

到auth資料夾下新增passport資料夾

在passport資料夾新增bearer資料夾及jwt資料夾(下一章要用)

新增http.strategy.ts

import { Injectable, UnauthorizedException } from '@nestjs/common';

import { AuthService } from 'auth/auth.service';
import {PassportStrategy} from '@nestjs/passport';
import {Strategy} from 'passport-http-bearer';

@Injectable()
// 要繼承@nest/passport下的PassportStrategy并傳入passport
// 本列是以http bearer為例
export class HttpStrategy extends PassportStrategy(Strategy) {

    constructor(private readonly authService: AuthService){
        super();
    }
    async validate(token: string){
        const user = await this.authService.validateUser(token);
        if(!user){ // 如果用token找不到使用者,就丟unauthorized exception
            return new UnauthorizedException();
        }
        return user; // 有找到使用者,passport會把user物件存在req中
    }
}

在AuthModule注冊provider

@Module({
    imports: [
        UserModule,
    ],
    providers: [
        AuthService,
        HttpStrategy,
    ],
})
export class AuthModule {}

到User controller套用@UseGuards()

修改users.controller.ts

import { AuthGuard } from '@nestjs/passport';

// UseGuards()傳入@nest/passport下的AuthGuard,并指定用bearer驗證
@UseGuards(AuthGuard('bearer'))
@Controller('users')
export class UsersController {
 ...
}

使用postman測試


2018111602.png

顯示401 Unauthoized

在authorization指定bearer token

2018111603.png

可以顯示users資料

下一章講JWT

推薦一下我的公眾號: 【 geekjc 】,微信號: 【 c8706288 】一起學習交流編程知識,分享經驗,各種有趣的事。

tuiguang.png
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容