Error unknown authentication strategy jwt

I'm submitting a... [ ] Regression [x] Bug report [ ] Feature request [ ] Documentation issue or request [ ] Support request => Please do not submit support request here, instead post your q...

I’m submitting a…


[ ] Regression 
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

I just updated to v6.0.4 and I’m using authguard with graphql & passport-jwt. However, I’m getting Error: Unknown authentication strategy «jwt»

Expected behavior

Minimal reproduction of the problem with instructions


// gql-auth.guard.ts
import { Injectable } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class GqlAuthGuard extends AuthGuard('jwt') {
  getRequest(context: GqlExecutionContext) {
    const ctx = GqlExecutionContext.create(context);
    return ctx.getContext().req;
  }
}

//jwt.strategy.ts
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy, VerifiedCallback } from 'passport-jwt';
import { UserService} from 'src/user/user.service';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(private userService: UserService) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: process.env.JWT_SECRET,
    });
  }

  async validate(payload: any, done: VerifiedCallback) {
    const user = await this.userService.findOneByPayload(payload);
    if (!user) {
      return done(new UnauthorizedException(), false);
    }

    return done(null, { id: user.id }, payload.iat);
  }
}

// auth.module.ts
import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { UserModule } from 'src/user/user.module';
import { AuthResolver } from './auth.resolver';

@Module({
  imports: [
    PassportModule.register({ defaultStrategy: 'jwt' }),
    JwtModule.register({ secretOrPrivateKey: process.env.JWT_SECRET }),
    UserModule,
  ],
  providers: [AuthResolver],
})
export class AuthModule {}

What is the motivation / use case for changing the behavior?

Environment


Nest version: 6.0.4

 
For Tooling issues:
- Node version: 10.15
- Platform:  Windows

Others:

Содержание

  1. Unit testing nestjs guards Unknown authentication strategy
  2. 1 Answer 1
  3. Unknown authentication strategy «jwt» #16
  4. Comments
  5. Footer
  6. Unknown authentication strategy jwt #198
  7. Comments
  8. Update:
  9. Update:
  10. Unknown authentication strategy «jwt» when use Request Scope Service #1870
  11. Comments
  12. I’m submitting a.
  13. Current behavior
  14. Expected behavior
  15. Minimal reproduction of the problem with instructions
  16. What is the motivation / use case for changing the behavior?
  17. Environment
  18. Unknown authentication strategy «jwt» #16
  19. Comments
  20. Footer

Unit testing nestjs guards Unknown authentication strategy

Trying to write unit tests as described here but no idea how to get around this error

The actual implementation works fine, I add it to a controller.

I don’t even need to add it as a provider or anything in my setup so not sure what other code to include.

I implemented a custom strategy which may be related

And of course MyStrategy is added as a provider in my app.

I have unit tests covering my custom strategy already so it is really just the guard left

EDIT:

Trying Jay’s suggestion below gets me a little closer but i’m still struggling.

It seems passport.use() expects a name and Strategy rather than a function (so TS compilation fails) so I tried

and the error disappears, but the test now outputs

Any further suggestions?

1 Answer 1

This is one of those quirky things with passport that I never thought I’d see. So, passport uses strategy names to determine what authentication method is actually being used, right? All of these strategies get registered to the passport context using passport.use(name, method) in the general scheme of things. In the context of Nest, this happens when you create a custom strategy, extend PassportStrategy and add the strategy as a provider as seen here. Later, the method passport.authenticate(strategy, (err, req, res, next) is called during the AuthGuard#canActivate method (the codes a bit complex, but this is where it happens). Because passport has never seen passport.use(‘test-jwt’, authMethod) in the context of your test, it ends up not knowing what to do other than throwing the error about «Unknown authentication strategy».

Normally, the validate method is what becomes the authMethod , but if you’re just needing this for the context of your test you can do something like

Источник

Unknown authentication strategy «jwt» #16

I watched your all 7 videos and wrote the code accordingly. I am getting the above error on passport

Unknown authentication strategy «jwt»

would you please help me how I can fix

The text was updated successfully, but these errors were encountered:

@umardraz I would suggest cloning the tabtracker app to your system, then bring it up in IDE app and search for ‘jwt’ and make comparisons. It sounds like you may have missed something. When I was working through the tutorial, I often had to refer back to the repos, which was a good exercise in and of itself. Also be careful about what version of packages are being installed (package.json). I have found to this point my main source of frustration has been incompatability issues. Case in point and slightly off topic, I spent a day trying to figure out an error being thrown when attempting to implement ‘moment’ and ‘moment-timezone’ only to find out the newer versions were failing to import appropriately once I had the older versions installed the libraries worked like a champ. I hope this advice is helpful.

Hi thanks for your reply.

Well I had fixed that actually require (‘./passport) was missing in app.js.

Now one mere thing. I want to use facebook, linkedin authentication using this tabtracker tutorial. Would you please help me what I need to do on vuejs and and express end?

@umardraz. This is where I would start. NodeJS — Login with Facebook and Passport js.
The souce to the repos is noted in the details. https://youtu.be/OMcWgmkMpEE

© 2023 GitHub, Inc.

You can’t perform that action at this time.

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.

Источник

Unknown authentication strategy jwt #198

I’m trying to run hapi, glue and jwt2. I found the example mentioned in FAQ, but I’m still not getting it to run. I have a prototype with 2 modules: auth and pinger(which replies pong). If I remove auth: ‘jwt’, server works, but no auth is required. If I add auth, I get error

And server, src/index.js

If config is needed, I can provide it. I have a feeling, that the auth plugin is not loaded. Anyway, this issue drives me up the wall. I could integrate the auth in the main file, but I don’t want to 🙂

Can someone point me to a right direction? 😆

The text was updated successfully, but these errors were encountered:

Glue v4.0.0 .
Hapi v15.1.1 .
hapi-auth-jwt2 v7.1.3

Update:

When I tried using Glue defined with only 1 (one) connection in my gist, it’s working.
server.js line: 13

29
and place comment /* */ at line: 22

results as below:

I already tried in pure HapiJS by re-write another code without Glue,
and returned as same, if got more than 1 (one) connection.

Previously, about 2 months ago, I had successful ran hapi-auth-jwt2 in pure HapiJS with multiple connections (2); not even using Glue .
Node v4.5.0
Hapi v14.2.0
hapi-auth-jwt2 v5.2.0

@anttilinno Maybe you should change the Issue title/subject to:

Not working on Hapi v15+ (or Glue) with multiple connections

Hm, I have only single connection 😄 Although it is defined in array.

@anttilinno have you try this way (for your case) ?
File: auth/index.js

Update:

IMHO, I think this is not for hapi-auth-jwt2 plugin issue.

I had tried in several different simulations, which return as Glue logic problem, then I tried on pure Hapi code, to get better minimalistic code .

  1. Require hapi module
  2. Create new Hapi.Server()
  3. Define server.connections()
  4. Register Hapi-Plugins into each connections by using server.register()
  • and if you were under the Glue in my understanding that it doesn’t have an event to patch some method or function to define some sub-process after current plugin registered from server.register() as callback(err) L163L301L324 before the next(err) tick process. L119 imho..
  • When you were implement auth.strategy() on multiple connections, you will need to define from connection.auth.strategy() , and for single connection may call from server.auth.strategy() , which implement from auth.scheme() .
  • And I think it should better to call after the plugin registered and before call the next(err) tick process. L119 imho..
  1. You may double-check if your preferred plugins on each connections, are they already registered by fetch it on server.registrations for single connection or connection.registrations for multiple connection.
  2. Register Hapi-Routes by call server.route() for a single connection, or may call from connection.route() from instance of multiple connections to define right into each connections.
  3. Start the server by call server.start()

I hope it’s not lot to taken, but it’s better to code pure in Hapi for several cases.

Источник

Unknown authentication strategy «jwt» when use Request Scope Service #1870

I’m submitting a.

Current behavior

When i import in JwtStrategy a service that has Request Scope , authentication does not work anymore, as i show in this repository: https://github.com/victorschinaider/nest-request-auth-bug.

Expected behavior

I expect that i can use request scope service in JwtStrategy.

Minimal reproduction of the problem with instructions

What is the motivation / use case for changing the behavior?

Environment

The text was updated successfully, but these errors were encountered:

You are not lone here, I also had the same issue. I don’t have a solution, i have been playing around with it for hours and no go.

You cannot use request scoped providers in passport strategy because passport itself is global (the package is not compatible with this feature). Hopefully, we will provide a more flexible @nestjs/auth package soon.

Is a more flexible @nestjs/auth package on the roadmap? @kamilmysliwiec
Had to do some annoying workarounds with middleware and request context to get this working 💯

I was so excited i could make a logger scoped with the request . only to be extremely disappointed.

Have a stack question open if anyone wants to chime in

Documentation at https://docs.nestjs.com/techniques/authentication should probably be updated to make this issue clear.

What are some of the workarounds people have come up with? I was wondering if using a middleware instead of using provider scope works as a workaround?

Update: @eropple/nestjs-auth exists, and it uses interceptors, as opposed to middleware.

@yaser-ali-s .. .made 2 loggers with different scopes and manually passed in the request where appropriate

Источник

Unknown authentication strategy «jwt» #16

I watched your all 7 videos and wrote the code accordingly. I am getting the above error on passport

Unknown authentication strategy «jwt»

would you please help me how I can fix

The text was updated successfully, but these errors were encountered:

@umardraz I would suggest cloning the tabtracker app to your system, then bring it up in IDE app and search for ‘jwt’ and make comparisons. It sounds like you may have missed something. When I was working through the tutorial, I often had to refer back to the repos, which was a good exercise in and of itself. Also be careful about what version of packages are being installed (package.json). I have found to this point my main source of frustration has been incompatability issues. Case in point and slightly off topic, I spent a day trying to figure out an error being thrown when attempting to implement ‘moment’ and ‘moment-timezone’ only to find out the newer versions were failing to import appropriately once I had the older versions installed the libraries worked like a champ. I hope this advice is helpful.

Hi thanks for your reply.

Well I had fixed that actually require (‘./passport) was missing in app.js.

Now one mere thing. I want to use facebook, linkedin authentication using this tabtracker tutorial. Would you please help me what I need to do on vuejs and and express end?

@umardraz. This is where I would start. NodeJS — Login with Facebook and Passport js.
The souce to the repos is noted in the details. https://youtu.be/OMcWgmkMpEE

© 2023 GitHub, Inc.

You can’t perform that action at this time.

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.

Источник

For web based applications, there are various authentication mechanisms available. To let your hapi server support a selected one, pick a plugin from the hapi ecosystem, provide the required configuration and you’re ready to go.

At some point, most of us hapi developers trap into an unknown authentication strategy <name> in <route-path> error and didn’t realize why this occurs.

Actually, the fix is kind of straight forward. Read on to get the details!

hapi Series Overview

  • hapi
  • Futureflix
  • Futureflix API
  • Build a Rate Limiter
  • JWT Authentication
  • Server
  • Authentication
  • Views
  • Plugins
  • Routes
  • Requests
  • Responses
  • Validation
  • Security
  • Logging
  • Testing
  • Deployments

  1. Get Your Server Up and Running

  2. v17 Upgrade Guide (Your Move to async/await)

  3. Become a Better Developer in 2018

  4. Become a Better Developer in 2017


  1. What You’ll Build


  2. Prepare Your Project: Stack & Structure


  3. Environment Variables and Storing Secrets


  4. Set Up MongoDB and Connect With Mongoose

  5. Sending Emails in Node.js


  6. Load the User’s Profile Picture From Gravatar Using Virtuals in Mongoose


  7. Implement a User Profile Editing Screen


  8. Generate a Username in Mongoose Middleware


  9. Displaying Seasons and Episodes for TV Shows with Mongoose Relationship Population


  10. Implementing Pagination for Movies


  11. Implement a Watchlist


  12. Create a Full Text Search with MongoDB


  1. Create a REST API with JSON Endpoints


  2. Update Mongoose Models for JSON Responses


  3. API Pagination for TV Shows


  4. Customize API Endpoints with Query Parameters


  5. Always Throw and Handle API Validation Errors


  6. Advanced API Validation With Custom Errors


  7. Create an API Documentation with Swagger


  8. Customize Your Swagger API Documentation URL


  9. Describe Endpoint Details in Your Swagger API Documentation


  10. 10 Tips on API Testing With Postman


  11. JWT Authentication in Swagger API Documentation


  12. API Versioning with Request Headers


  1. IP-Based Rate Limits (Part 1 of 7)


  2. Rate Limits for Routes (Part 2 of 7)


  3. Dynamic Rate Limits (Part 3 of 7)


  4. Render a “Rate Limit Exceeded” View (Part 4 of 7)


  5. Show “Rate Limit Exceeded” Error on Login (Part 5 of 7)


  6. Disable Rate Limiting (Part 6 of 7)


  7. Rate Limiter Refactoring & Cleanup (Part 7 of 7)


  1. API Login With Username and Password to Generate a JWT


  2. JWT Authentication and Private API Endpoints


  3. Refresh Tokens With JWT Authentication


  4. Create a JWT Utility


  5. JWT Refresh Token for Multiple Devices


  6. Check Refresh Token in Authentication Strategy


  7. Rate Limit Your Refresh Token API Endpoint


  8. How to Revoke a JWT


  9. Invalidate JWTs With Blacklists


  10. JWT Logout (Part 1/2)


  11. JWT “Immediate” Logout (Part 2/2)


  12. A Better Place to Invalidate Tokens


  13. How to Switch the JWT Signing Algorithm


  14. Roll Your Own Refresh Token Authentication Scheme


  15. JWT Claims 101


  16. Use JWT With Asymmetric Signatures (RS256 & Co.)


  17. Encrypt the JWT Payload (The Simple Way)


  18. Increase JWT Security Beyond the Signature


  19. Unsigned JSON Web Tokens (Unsecured JWS)


  20. JWK and JWKS Overview


  21. Provide a JWKS API Endpoint


  22. Create a JWK from a Shared Secret


  23. JWT Verification via JWKS API Endpoint


  24. What is JOSE in JWT


  25. Encrypt a JWT (the JWE Way)


  26. Authenticate Encrypted JWTs (JWE)


  27. Encrypted and Signed JWT (Nested JWT)


  28. Bringing Back JWT Decoding and Authentication


  29. Bringing Back JWT Claims in the JWT Payload

  1. How to Run Separate Frontend and Backend Servers Within a Single Project

  2. How to Use Server Labels


  3. How to Correctly Stop Your Server and Close Existing Connections


  1. Basic Authentication With Username and Password

  2. Authentication and Remember Me Using Cookies

  3. How to Set a Default Authentication Strategy


  4. Define Multiple Authentication Strategies for a Route

  5. Restrict User Access With Scopes


  6. Show „Insufficient Scope“ View for Routes With Restricted Access


  7. Access Restriction With Dynamic and Advanced Scopes

  8. hapi — How to Fix „unknown authentication strategy“
  9. Authenticate with GitHub And Remember the Login

  10. Authenticate with GitLab And Remember the User


  11. How to Combine Bell With Another Authentication Strategy


  12. Custom OAuth Bell Strategy to Connect With any Server

  13. Redirect to Previous Page After Login


  14. How to Implement a Complete Sign Up Flow With Email and Password


  15. How to Implement a Complete Login Flow


  16. Implement a Password-Reset Flow


  1. Views in hapi 9 (and above)


  2. How to Render and Reply Views


  3. How to Reply and Render Pug Views (Using Pug 2.0)


  4. How to Create a Dynamic Handlebars Layout Template


  5. Create and Use Handlebars Partial Views


  6. Create and Use Custom Handlebars Helpers

  7. Specify a Different Handlebars Layout for a Specific View

  8. How to Create Jade-Like Layout Blocks in Handlebars

  9. Use Vue.js Mustache Tags in Handlebars Templates


  10. How to Use Multiple Handlebars Layouts


  1. Extend Your Server Functionality With Plugins


  2. Create Your Own Custom Plugin

  3. How to Register Plugins for a Selected Server Instance

  4. hapi Plugin for Client Geo Location (by Future Studio 🚀)


  5. Increase Development Speed With Errors in the Browser or as JSON Response


  1. Route Handling and Drive Traffic to Your Server


  2. How to Serve Static Files (Images, JS, CSS, etc.)


  3. How to Use Query Parameters

  4. Optional Path Parameters

  5. Multi-Segment/Wildcard Path Parameters

  6. Ignore Trailing Slashes on Route Paths

  7. How to Fix “Unsupported Media Type”


  1. How to Access and Handle Request Payload


  2. Access Request Headers


  3. How to Manage Cookies and HTTP States Across Requests

  4. Detect and Get the Client IP Address

  5. How to Upload Files


  6. Quick Access to Logged In User in Route Handlers

  7. How to Fix “handler method did not return a value, a promise, or throw an error”

  8. How to Fix “X must return an error, a takeover response, or a continue signal”


  1. How to Reply a JSON Response


  2. How to Set Response Status Code


  3. How to Handle 404 Responses for Missing Routes

  1. Query Parameter Validation With Joi

  2. Path Parameter Validation With Joi

  3. Request Payload Validation With Joi

  4. Validate Query and Path Parameters, Payload and Headers All at Once on Your Routes

  5. Validate Request Headers With Joi


  6. Reply Custom View for Failed Validations


  7. Handle Failed Validations and Show Errors Details at Inputs

  8. How to Fix AssertionError, Cannot validate HEAD or GET requests


  1. Add CSRF Protection on Forms and API Endpoints


  1. Report Errors to Sentry


  2. Don’t Report Errors to Sentry in Development Mode


  3. Logging Fundamentals


  4. Log to Console With Good


  5. Log to File With Good

  1. Getting Started With Testing Using Lab and Code

  2. Run Tests with Assertions using Code

  3. Test Route Handlers by Injecting Requests

  4. Inject Request Payload, Headers and Parameters While Testing Route Handlers

  1. Zero-Downtime Deployments Using PM2

The Problem

Independent of your app’s authentication strategy, the following error stack trace probably feels familiar:

$ node server.js

/Users/marcuspoehls/Dev/JS/nodejs-tutorials-hapi/node_modules/hapi/node_modules/hoek/lib/index.js:736
    throw new Error(msgs.join(' ') || 'Unknown error');
    ^

Error: Unknown authentication strategy session in /  
    at Object.exports.assert (/Users/marcuspoehls/Dev/JS/nodejs-tutorials-hapi/node_modules/hapi/node_modules/hoek/lib/index.js:736:11)
    …

In essence, the defined authentication strategy called session is not available for the route with path /. Now you might think that you’re creating the session strategy in your project and hapi still can’t find it. So what’s the issue?

The Solution(s)

The actual problem is that the session strategy is created too late. A route that requires the session strategy is registered before session is known to the server.

Now that you know the problem (a strategy not created when the route with related authentication scheme should be registered), you can put your solution in place. Depending on your application setup, there are different approaches on how to implement the solution.

Create a Dedicated Authentication Plugin

Composing your application with individual plugins is the recommended way in hapi. If you’re already splitting the different parts of your apps into separate plugins, there’s a straightforward way to fix the problem: create a dedicated authentication plugin.

Create the Plugin

The following snippet illustrates the authentication plugin by using the hapi-auth-cookie dependency to create the session strategy.

Let’s name the following snippet authentication.js, so we can easily refer to it:

authentication.js

const Hoek = require('hoek')

async function register (server, options) {  
  // register dependency to hapi-auth-cookie
  // and make sure it’s available to this plugin
  await server.register({
    plugin: require('hapi-auth-cookie')
  })

  // configure the "session" strategy
  server.auth.strategy('session', 'cookie', {
    password: 'ThisIsASecretPasswordForTheAuthCookie',
    redirectTo: '/',
    isSecure: process.env.NODE_ENV === 'production'
  })
}

exports.plugin = {  
  register,
  name: 'authentication',
  version: '1.0.0',
  once: true
}

The code snippet above uses the hapi-auth-cookie module as a dependency. Also, this specific authentication plugin (see the plugin’s name attribute) registers its dependencies itself. Please make sure you don’t register the hapi-auth-cookie twice to your hapi server, then you’ll get an error.

Notice the once: true within the plugin’s attributes. This configuration tells hapi to register this plugin only once on the same server.

What about server.dependency?

Did you think about using server.dependency([ 'hapi-auth-cookie' ]) to declare the dependency between authentication and hapi-auth-cookie (or further plugins)?

Sadly, hapi doesn’t make sure that plugins are registered in order and therefore you need to make sure the hapi-auth-cookie plugin is definitely registered before authentication should be plugged into your server.

Now that you’ve set the dependency within your authentication plugin, go ahead and create the session strategy based on the cookie scheme. You need to do that within the callback function of server.register().

With the call of next(), hapi knows that your plugin is registered and the next one can be processed.

Use Authentication Plugin in Your App

In your plugins that require authentication and specifically the session strategy, register the authentication plugin (from the code block above) as a dependency.

The authentication plugin is your custom one (from the code block above, which we named authentication.js). Of course, you can name it whatever you want :)

Let’s name the following snippet your-plugin.js to get a reference within this tutorial.

your-plugin.js

async function register (server, options) {  
  await server.register([
    {
      register: require('./path/to/authentication')
    }
    {
      register: require('vision') // if you want view rendering support
    },
  ])

  // your plugin logic goes here
  // like "server.route(yourRoutes)"

  // tell hapi it’s safe to process the next plugin :)
}

Within your application plugins that rely on the authentication plugin as a dependency, make sure you install it. The once: true attribute of authentication makes sure hapi only registers the plugin once for the same server.

Having the dependencies installed, do your individual configuration, add routes, extend the request lifecycle, etc.

Register Plugins to Your Server

The dedicated authentication plugin is a requirement for other plugins. Individual plugins should make sure their dependencies are installed by doing it themselves.

That’s why you only need to register your “main” plugins and they individually handle their dependencies themselves.

const Hapi = require('hapi')  
const server = new Hapi.Server()

// register plugins to server instance
async function liftOff () {  
  server.register([
    {
      plugin: require('./path/to/your-plugin')
    },
    {
      plugin: require('./path/to/another-plugin')
    },
    {
      plugin: require('./path/to/the-fancy-funky-plugin')
    }
  ])

  try {
    await server.start()
    console.log('Server running at: ' + server.info.uri)
  } catch (err) {
    console.log(err)
    process.exit(1)
  }
}

liftOff()  

Not Using Plugins: Ensure a Server Composition Flow

If you don’t compose your hapi app with individual plugins, make sure that you register the used plugins (e.g., vision, inert, etc.) first. Then create the authentication strategies, set the view configuration or do everything else you want to use in your routes.

Having the plugins registered, views configured or authentication in place, register all your routes to the hapi server instance. Adding the routes to the hapi server with (all batteries included) should go well.

Outlook

In this tutorial you’ve learned how to fix the actual problem for the „unknown authentication strategy“ error. This error occurs, because the given strategy is not available to the server yet while a route should be added and requires the strategy.

Solve this problem by creating a dedicated authentication plugin that can be defined as a dependency for your individual application plugins. If you don’t use plugins to compose your app, make sure your application flow follows the correct path of registering dependencies first, configure the authentication strategies and than add routes.

Want to learn more on how to access and handle the request payload in hapi? The linked tutorial is for you!

We’re happy to hear your thoughts and comments. Please don’t hesitate to use the comments below or find us on Twitter @futurestud_io. Let us know what you think!

Enjoy coding & make it rock!

Build “Futureflix” and be hapi 😉

Futureflix is your own Netflix-like streaming platform and the app you’re building throughout the
learn hapi learning path.

Other courses in the Internet use basic and simple examples. That leaves you with a guessing game on complex features.

In learn hapi, you’ll implement an
advanced hapi application from start to end

Grow yourself by working through user
accounts & authentication,
security, developer goodies,
sending emails, building a
REST API,
full text search, powerful
pagination.

У меня есть пользовательская служба, которая обрабатывает регистрацию, вход в систему и некоторые другие функции. Я когда-то работаю над приложением с более чем 10 модулями. Но я заметил, что каждый раз, когда я внедряю другую службу и пытаюсь использовать любую конечную точку, я получаю эту ошибку "Unknown authentication strategy "jwt". Ошибка в swagger: —

Internal Server Error
Response body

{
  "statusCode": 500,
  "message": "Internal server error"
}

Как только я удаляю внедренную службу из пользовательского модуля, все снова в порядке. Я пытался исправить это, потому что мне нужно использовать эту службу внутри пользовательского модуля.

Это jwt.Strategy.ts

import { Injectable, HttpException, HttpStatus } from "@nestjs/common";
import { PassportStrategy } from '@nestjs/passport';
import { Strategy, ExtractJwt, VerifiedCallback } from "passport-jwt";
import { AuthService } from './auth.service';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
    constructor(private authService: AuthService) {
        super({
            jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
            ignoreExpiration: false,
            secretOrKey: process.env.SECRETKEY
        });
    }

    async validate(payload: any, done: VerifiedCallback) {
        const user = await this.authService.validateUser(payload);
        try {
            if (user) {
                //return user;
                return done(null, user, payload.iat)
            } else if (user == null) {
                const Terminal = await this.authService.validatePos(payload);
                return done(null, Terminal, payload.iat)
            }
            else {
                return done(
                    //throw new UnauthorizedException();
                    new HttpException('Unauthorised access', HttpStatus.UNAUTHORIZED),
                    false,
                );
            }

        } catch (error) {
            return error;
        }
    }
}

Это AuthModule

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UserService } from '../user/user.service';
import { UserSchema } from '../user/user.schema';
import { MongooseModule } from '@nestjs/mongoose';
import { JwtStrategy } from './jwt.strategy';
import { ActivityLogService } from '../activity-log/activity-log.service';
import { ApiKeyStrategy } from './apiKey.strategy';
import { PassportModule } from "@nestjs/passport";

@Module({
    imports: [MongooseModule.forFeature([{ name: 'User', schema: UserSchema }]),
    PassportModule.register({
        secret: "mysec"
    }),
        ActivityLogService],
    providers: [AuthService, UserService, JwtStrategy, ApiKeyStrategy, ActivityLogService],
    exports: [AuthService],
    controllers: []
})
export class AuthModule { }

Это api.strategy.ts

import { HeaderAPIKeyStrategy } from 'passport-headerapikey';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
import { AuthService } from './auth.service';

@Injectable()
export class ApiKeyStrategy extends PassportStrategy(HeaderAPIKeyStrategy) {
    constructor(private authService: AuthService) {
        super({
            header: 'api_key',
            prefix: ''
        }, true,
            (apikey: string, done: any, req: any, next: () => void) => {
                const checkKey = this.authService.validateApiKey(apikey);
                if (!checkKey) {
                    return done(
                        new HttpException('Unauthorized access, verify the token is correct', HttpStatus.UNAUTHORIZED),
                        false,
                    );
                }
                return done(null, true, next);
            });
    }
}

Это authService


import { Injectable } from '@nestjs/common';
import { sign } from 'jsonwebtoken';
import { UserService } from '../user/user.service';
import { TerminalService } from '../terminal/terminal.service';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { Terminal } from '../terminal/interfaces/terminal.interface';


@Injectable()
export class AuthService {
    constructor(private userService: UserService, @InjectModel('Terminal') private terminalModel: Model<Terminal>,) { }

    //generate token for user
    async signPayLoad(payload: any) {
        return sign(payload, process.env.SECRETKEY, { expiresIn: '1h' });
    }

    //find user with payload
    async validateUser(payload: any) {
        const returnuser = await this.userService.findByPayLoad(payload);
        return returnuser;
    }

    //generate token for Posy
    async signPosPayLoad(payload: any) {
        return sign(payload, process.env.SECRETKEY, { expiresIn: '24h' });
    }

    //find terminal with payload
    async validatePos(payload: any) {
        const { terminalId } = payload;
        const terminal = await this.terminalModel.findById(terminalId);
        return terminal;
    }

    validateApiKey(apiKey: string) {
        const keys = process.env.API_KEYS;
        const apiKeys = keys.split(',');
        return apiKeys.find(key => apiKey === key);
    }
}


Это пользовательский сервис

import { Injectable, HttpException, HttpStatus, Inject } from '@nestjs/common';
import { User } from './interfaces/user.interface';
import { Model } from 'mongoose';
import { InjectModel } from '@nestjs/mongoose';
import { LoginUserDto } from './login-user.dto';
import { ActivityLogService } from '../activity-log/activity-log.service';
import { UpdateUserDTO } from './dtos/update_user.dto';

@Injectable()
export class UserService {
    constructor(@InjectModel('User') private userModel: Model<User>,
        private activityLogService: ActivityLogService,
    ) { }
    
    //Login user
    private users = [
        {
            "userId": 1,
            "name": "John Doe",
            "username": "john",
            "password": "john123"
        },
    ]
    async login(loginDTO: LoginUserDto) {

        const { email, password } = loginDTO;

        return await this.users.find(users => users.username == email)
    }

    async findByPayLoad(payload: any) {
        const { userId } = payload;
        return await this.userModel.findById(userId)
    }
    async getAllUser() {
        return this.users;
    }
}

Я не могу понять, что я делаю неправильно

Помимо того, что кодом сложно манипулировать и определять, что происходит, службы находятся в местах, где они не должны находиться, и повторных экземпляров служб повсюду, виновником того, почему вы получаете ошибку, является просто то, что вы никогда не регистрируете PassportModule от @nestjs/passport


РЕДАКТИРОВАТЬ 07.01.2017

Возвращаясь к этому ответу примерно через полтора года, похоже, что реальная проблема заключается в использовании в стратегии поставщика с областью действия REQUEST. В документах Nest явно упоминается, что это невозможно сделать напрямую, но также есть обходной путь для это.


3

Jay McDoniel
7 Янв 2022 в 23:36

#node.js #typescript #passport.js #nestjs #passport-local

#node.js #машинописный текст #passport.js #гнездышко #паспорт-местный

Вопрос:

У меня есть этот код в NestJS со следующими файлами ниже, но теперь в нем написано «Неизвестная стратегия аутентификации «локальная»», я уже искал решения, и все они указывают на ошибку импорта, но у меня есть локальная стратегия, импортированная в auth.module и app.module (я уже протестировал ее удаление из app.module, но это ничего не меняет).

приложение.модуль.ts

 import { Module } from '@nestjs/common';  import { AppController } from './app.controller';  import { AppService } from './app.service';  import { ThrottlerModule } from '@nestjs/throttler';  import { MongooseModule } from '@nestjs/mongoose';  import { AuthModule } from './auth/auth.module';  import { UsersModule } from './users/users.module';  import { LocalStrategy } from './auth/local.strategy';   @Module({  imports: [  MongooseModule.forRoot(  'mongodb srv://user:password@db.db.mongodb.net/db?retryWrites=trueamp;w=majority',  ),  ThrottlerModule.forRoot({  ttl: 60,  limit: 10,  }),  AuthModule,  UsersModule,  ],  controllers: [AppController],  providers: [AppService, LocalStrategy],  })  export class AppModule {}  

auth.модуль.ts

 import { Module } from '@nestjs/common';  import { AuthService } from './auth.service';  import { UsersModule } from '../users/users.module';  import { PassportModule } from '@nestjs/passport';  import { LocalStrategy } from './local.strategy';  import { JwtModule } from '@nestjs/jwt';  import { JwtStrategy } from './jwt.strategy';  import 'dotenv/config';   @Module({  imports: [  UsersModule,  PassportModule,  JwtModule.register({  secret: process.env.JWTSECRET,  signOptions: { expiresIn: '60s' },  }),  ],  providers: [AuthService, LocalStrategy, JwtStrategy],  exports: [AuthService],  })  export class AuthModule {}  

local.strategy.ts

 import { Strategy } from 'passport-local';  import { PassportStrategy } from '@nestjs/passport';  import { Injectable, UnauthorizedException } from '@nestjs/common';  import { AuthService } from './auth.service';   @Injectable()  export class LocalStrategy extends PassportStrategy(Strategy) {  constructor(private authService: AuthService) {  super({ usernameField: 'email' });  }   async validate(email: string, password: string): Promiselt;anygt; {  const user = await this.authService.validateUser(email, password);  if (!user) {  throw new UnauthorizedException();  }  return user;  }  }  

app.controller.ts

 import {  Controller,  Request,  Post,  UseGuards,  Res,  Get,  Body, } from '@nestjs/common'; import { AuthService } from './auth/auth.service'; import { MakeAuthDto } from './auth/dto/make-auth.dto'; import { JwtAuthGuard } from './auth/jwt-auth.guard'; import { LocalAuthGuard } from './auth/local-auth.guard'; import { Roles } from './utils/decorators/roles.decorator'; import { Role } from './utils/enums/role.enum'; import { RolesGuard } from './utils/guards/roles.guard';  @Controller() export class AppController {  constructor(private authService: AuthService) {}   @UseGuards(LocalAuthGuard)  @Post('auth/login')  async login(  @Body() _: MakeAuthDto,  @Request() req,  @Res({ passthrough: true }) res,  ) {  console.log(req.user);  const access_token = await this.authService.login(req.user);  res.cookie('jwt', access_token);  return req.user;  }   @UseGuards(JwtAuthGuard, RolesGuard)  @Roles(Role.Admin)  @Get('tests')  getProfile(@Request() req) {  return req.user;  } }  

local-auth.guard.ts

 import { Injectable } from '@nestjs/common';  import { AuthGuard } from '@nestjs/passport';   @Injectable()  export class LocalAuthGuard extends AuthGuard('local') {}  

auth.service.ts

 import { Injectable } from '@nestjs/common'; import { UsersService } from 'src/users/users.service'; import { JwtService } from '@nestjs/jwt'; import { UserDocument } from 'src/users/entities/user.entity';  @Injectable() export class AuthService {  constructor(  private usersService: UsersService,  private jwtService: JwtService,  ) {}   async validateUser(email: string, pass: string): Promiselt;UserDocument | anygt; {  const user = await this.usersService.findOne(email);  if (user amp;amp; (await user.compareHash(pass))) {  const { password, ...result } = user.toObject();  await this.usersService.updateLastLogin(user._id);  return result;  }  return null;  }   async login(user: UserDocument): Promiselt;stringgt; {  const payload = { email: user.email, sub: user._id, roles: user.roles };  return this.jwtService.sign(payload);  } }  

jwt-auth.guard.ts

 import { Injectable } from '@nestjs/common';  import { AuthGuard } from '@nestjs/passport';   @Injectable()  export class JwtAuthGuard extends AuthGuard('jwt') {}  

jwt.strategy.ts

 import { ExtractJwt, Strategy } from 'passport-jwt'; import { PassportStrategy } from '@nestjs/passport'; import { Injectable } from '@nestjs/common'; import 'dotenv/config';  const cookieExtractor = function (req) {  let token = null;  if (req amp;amp; req.cookies) {  token = req.cookies['jwt'];  }  return token; };  @Injectable() export class JwtStrategy extends PassportStrategy(Strategy) {  constructor() {  super({  jwtFromRequest: ExtractJwt.fromExtractors([cookieExtractor]),  ignoreExpiration: false,  secretOrKey: process.env.JWTSECRET,  });  }   async validate(payload: any) {  return { userId: payload.sub, email: payload.email, roles: payload.roles };  } }  

введите описание изображения здесь

Ни один подобный вопрос о stackoverflow не решил мою проблему, кто-нибудь знает, что это может быть?

Комментарии:

1. Не уверен, что это технически проблема, но с новейшей версией passport 0.5.0 вам нужно позвонить passport.initialize() , например, app.use(passport.initialize()) для приложения на основе express. Интересно, может ли это каким-то образом быть причиной.

2. @AlexanderStaroselsky Куда мне нужно это поместить?

3. Ну, в стандартном экспресс-приложении это было бы просто что-то вроде этого в главном файле app.js . Вы можете попробовать просто выполнить use инструкцию в своем main.ts (файле инициализации) или аналогичном. import * as passport from 'passport'; //.. app.use(passport.initialize());

4. Область действия вашего UsersService запроса ограничена?

Понравилась статья? Поделить с друзьями:
  • Error unity log missingmethodexception
  • Error unit1 pas 62 missing operator or semicolon
  • Error unit1 pas 37 expected but found
  • Error unexpectedly disconnected from boot status daemon
  • Error unexpected tab character