0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[NestJs][WebSocket.io]Jwt認証の実装方法

Posted at

はじめに

本記事は表題の通り、NestJsでWebsocket.ioを使用する際、Jwt認証を行う方法について記載します。
実装方法については以下を参考にしてください。わかりやすかったです。

(推奨)handleConnectionで認証を行う

handleConnection内で認証を行います。
また、定期的にトークンの有効期限の確認も行います。

フロント側でauthにトークンを付与します。

フロント側
    const socket = io('http://localhost:3001', {
      auth: {
        token: `Bearer ${accessToken.data.accessToken}`,
      },
    });

NestJs側でトークンを取得、configServiceを使用して検証を行います。

NestJS側
  handleConnection(client: Socket) {
    const tokenVerificationInterval = setInterval(() => {
      try {
        const token = client.handshake.auth.token.startsWith('Bearer ') ? client.handshake.auth.token.slice(7) : client.handshake.auth.token;
        const secret = this.configService.get<string>('JWT_SECRET_KEY');
        const decoded = this.jwtService.verify(token, { secret });
      } catch (error) {
        // トークンが無効な場合、切断する
        console.log('トークンが無効または期限切れです。接続を切断します...');
        client.disconnect(true);
      }
    }, 60000); // 例: 60秒ごとにトークンの検証を行う

    client.on('disconnect', () => {
      clearInterval(tokenVerificationInterval);
    });

(非推奨)guardを実装して関数ごとにアクセスを制限する

@UseGuardsを使用して関数単位でアクセスを制限する方法もありますが、
関数単位での制限は可能ですが、WebSocket接続自体を防ぐことはできません。
そのため非推奨です。

以下のような形で独自のguardを実装してください

import { ExtractJwt, Strategy as BaseJwtStrategy } from 'passport-jwt';

import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { PassportStrategy } from '@nestjs/passport';
import { JWTPayload, JWTStrategyPayload } from '../dto/jwt-payload';
import { Request } from 'express';

@Injectable()
export class JwtStrategy extends PassportStrategy(BaseJwtStrategy) {
  constructor(configService: ConfigService) {
    super({
      // Authorization bearerからトークンを読み込む関数を返す
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: configService.get<string>('JWT_SECRET_KEY'),
      passReqToCallback: true,
    });
  }
}

終わり

業務で実装した内容が多かったので、サンプルコードは大部分を割愛しています。
ご了承ください。

WebSocketの実装方法自体はすぐ見つかったのですが、
業務で使用するため認証が必要になり、苦労しました。

他にも問題がいくつかあり、より良い実装を模索中です。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?