いくつかのプロジェクトで使用するために、配布可能な認証ライブラリを実装したいと思います。ライブラリはJWT認証方式を実装する必要があります。コードは次のとおりです。
jwt.strategy.ts:
import {ExtractJwt, Strategy} from 'passport-jwt';
import {PassportStrategy} from '@nestjs/passport';
import {Injectable} from '@nestjs/common';
import {JwtPayload, User} from './interfaces';
import {ConfigService} from "./config.service";
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
constructor(private readonly configService: ConfigService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: configService.get('secretOrPrivateKey'),
});
}
async validate(payload: JwtPayload): Promise<User> {
return {
uuid: payload.uuid,
email: payload.email,
}
}
}
jwt.auth.module.ts:
import {Module, DynamicModule} from '@nestjs/common';
import {JwtModule} from '@nestjs/jwt';
import {JwtStrategy} from './jwt.strategy';
import {PassportModule} from '@nestjs/passport';
import {ConfigService} from "./config.service";
import {JwtOptions} from "./interfaces/jwt.options";
@Module({
})
export class JwtAuthModule {
static forRoot(jwtOptions): DynamicModule {
return {
module: JwtAuthModule,
imports: [
// JwtModule.register(jwtOptions),
// PassportModule.register({defaultStrategy: 'jwt'}),
],
providers: [
JwtStrategy,
{
provide: ConfigService,
useValue: new ConfigService(jwtOptions),
}
],
exports: [ConfigService, JwtStrategy]
};
}
}
これをapp.module.tsにインポートしました:
import { Module, NestModule, HttpModule } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { environment } from './environments';
import { AuthModule } from './auth/auth.module';
import { PermissionModule } from './permission/permission.module';
import {JwtAuthModule} from '@pe/nest-kit';
import {JwtModule} from '@nestjs/jwt';
import {PassportModule} from '@nestjs/passport';
@Module({
imports: [
JwtModule.register(environment.jwtOptions),
PassportModule.register({defaultStrategy: 'jwt'}),
JwtAuthModule.forRoot(environment.jwtOptions),
HttpModule,
AuthModule,
PermissionModule,
MongooseModule.forRoot(environment.mongodb),
],
})
export class ApplicationModule implements NestModule {
configure() {
}
}
ただし、プロジェクトのURLを開こうとするたびに、エラーが発生します。
[ネスト] 27645-24.10.2018、15:23:26 [ExceptionsHandler]不明な認証戦略 "jwt" + 4119msエラー:不明な認証戦略 "jwt"を試行中(/ home/user/workspace/permits/node_modules/passport/lib /middleware/authenticate.js:187:37)at authenticate(/home/user/workspace/permissions/node_modules/passport/lib/middleware/authenticate.js:363:7)at Promise(/ home/user/workspace/permissions /node_modules/@nestjs/passport/dist/auth.guard.js:83:3)/home/user/workspace/permissions/node_modules/@nestjs/passport/dist/auth.guard.jsの新しいPromise()で: MixinAuthGuardで75:83。 (/home/user/workspace/permissions/node_modules/@nestjs/passport/dist/auth.guard.js:47:36)Generator.next()at/home/user/workspace/permits/node_modules/@ nestjs/passport/dist/auth.guard.js:19:71 at new Promise()at __awaiter(/home/user/workspace/permissions/node_modules/@nestjs/passport/dist/auth.guard.js:15:12)at MixinAuthGuard.canActivate(/home/user/workspace/permissions/node_modules/@nestjs/passport/dist/auth.guard.js:40:20)at GuardsConsumer.tryActivate(/ home/user/workspace/permissions/node_modules/@ nestjs /core/guards/guards-consumer.js:13:34)at canActivateFn(/home/user/workspace/permissions/node_modules/@nestjs/core/router/router-execution-context.js:97:59)at/home/user /ワークスペース/permissions/node_modules/@nestjs/core/router/router-execution-context.js:47:37(/home/user/workspace/permissions/node_modules/@nestjs/core/router/router-proxy) .js:8:23 at Layer.handle [as handle_request](/ home/user/workspace/permissions/node_modules/express/lib/router/layer.js:95:5)
私は何が間違っているのですか?
これはgithubの私のコードです: https://github.com/riadhriadh/prototype_nestjs/tree/dev
jwt.strategy.tsで
import * as passport from 'passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { Injectable } from '@nestjs/common';
import { AuthService } from '../auth.service';
const config_projet =require("./projet_config");
@Injectable()
export class JwtStrategy extends Strategy {
constructor(private readonly authService: AuthService) {
super(
{
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
passReqToCallback: true,
secretOrKey: config_projet.secret,
},
async (req, payload, next) => await this.verify(req, payload, next)
);
passport.use(this);
}
public async verify(req, payload, done) {
const isValid = await this.authService.validateUser(payload);
if (!isValid) {
return done('Unauthorized', false);
}
done(null, payload);
}
}
===================
import { Injectable } from '@nestjs/common';
import * as jwt from 'jsonwebtoken';
import { UsersService } from 'users/users.service';
const config_projet =require("../projet_config");
var fs = require('fs');
@Injectable()
export class AuthService {
constructor(private readonly usersService: UsersService) { }
async createToken(email: string) {
const expiresIn = 6000 * 60;
const secretOrKey = fs.readFileSync("./key.pem");;
const user = { email };
const token = jwt.sign(user, secretOrKey, { audience: 'urn:foo' });
return { expires_in: expiresIn, token };
}
async validateUser(signedUser): Promise<boolean> {
if (signedUser && signedUser.email) {
return Boolean(this.usersService.getUserByEmail(signedUser.email));
}
return false;
}
}
==============================
で:auth.controller.ts
================================
import { Controller, Post, HttpStatus, HttpCode, Get, Response, Body } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersService } from 'users/users.service';
import { User } from 'users/user.entity';
@Controller("auth")
export class AuthController {
constructor(
private readonly authService: AuthService,
private readonly userService: UsersService
) {}
@Post('login')
async loginUser(@Response() res: any, @Body() body: User) {
if (!(body && body.email && body.password)) {
return res.status(HttpStatus.FORBIDDEN).json({ message: 'Email and password are required!' });
}
const user = await this.userService.getUserByEmail(body.email);
if (user) {
if (await this.userService.compareHash(body.password, user.password)) {
return res.status(HttpStatus.OK).json(await this.authService.createToken(user.email));
}
}
return res.status(HttpStatus.FORBIDDEN).json({ message: 'Email or password wrong!' });
}
@Post('register')
async registerUser(@Response() res: any, @Body() body: User) {
if (!(body && body.email && body.password && body.last_name && body.first_name)) {
return res.status(HttpStatus.FORBIDDEN).json({ message: 'Username and password are required!' });
}
let user = await this.userService.getUserByEmail(body.email);
if (user) {
return res.status(HttpStatus.FORBIDDEN).json({ message: 'Email exists' });
} else {
let userSave = await this.userService.create(body);
if(userSave){
body.password=undefined;
}
return res.status(HttpStatus.OK).json(userSave);
}
}
}
解決しました。 PHPでは、プロジェクト全体に対して1つの依存関係ツリーがあります。 npmでは、各パッケージに独自の依存関係サブツリーがあります。例:
- パスポート
-@ pe/nest-kit
- - パスポート
nest-kitは----passport
のオブジェクトを使用しますが、ルートプロジェクトは同じ名前のタイプのオブジェクトを使用しますが、実際にはこれはnodejsコンパイラの別のタイプです。解決策は、AuthGuardを@ nestjs/passportから@pe/nest-kitを介して再エクスポートすることです。これは機能します。
必要なパッケージをすべて追加しましたか?認証ドキュメントを確認してみてください https://docs.nestjs.com/techniques/authentication JWTの扱い方をよく説明しています。