Skip to content

How to know which strategy was used by fastify-auth?聽#1083

Open

Description

@fusionfoxy

馃挰 Question here

I use fastify-bearer-auth with fastify-auth to authenticate requests. I have a few endpoints where the bearer auth is optional. This pretty much follows this example perfectly: https://github.com/fastify/fastify-bearer-auth?tab=readme-ov-file#integration-with-fastifyauth

However, my endpoints should respond differently to the request depending on which of the two strategies was used.

So, in my request handler, how can I know if fastify-auth authenticated the request with bearer auth or as anonymous?

  await fastify
    .register(auth)
    .register(bearerAuthPlugin, { addHook: false, keys, verifyErrorLogLevel: 'debug' })
    .decorate('allowAnonymous', function (req, reply, done) {
      if (req.headers.authorization) {
        return done(Error('not anonymous'))
      }
      return done()
    })

  fastify.route({
    method: 'GET',
    url: '/multiauth',
    preHandler: fastify.auth([
      fastify.allowAnonymous,
      fastify.verifyBearerAuth
    ]),
    handler: function (req, reply) {
      if (AUTH WAS BEARER) { // <--- How to make this check?
        reply.send({ auth: 'bearer' })
      } else {
        reply.send({ auth: 'anonymous'});
      }
    }
  })

Your Environment

  • node version: 23
  • fastify version: >=5.2.0
  • os: Linux

Activity

  1. pckrishnadas88 commented on Dec 3, 2025

    @pckrishnadas88
    // server.js
    
    const fastify = require('fastify')({ logger: true });
    const auth = require('@fastify/auth');
    const bearerAuthPlugin = require('@fastify/bearer-auth');
    
    // 1. Define the secret keys for bearer auth
    // The token 'my-secret-token' is the only valid key.
    const keys = new Set(['my-secret-token']);
    
    // 2. Custom verification function for fastify-bearer-auth
    // This function explicitly sets req.authData upon successful verification.
    async function verifyKeyAndSetUser(key, req) {
      // Log the key received for debugging
      req.log.info({ received_key: key }, 'Bearer Auth received key');
    
      if (keys.has(key)) {
        // SUCCESS: Explicitly set the authenticated user data on the request.
        // This is the key fix for the multi-auth chaining issue.
        req.authData = { id: key, role: 'authenticated_user', token_used: true };
        
        // Return true to indicate successful authentication.
        return true; 
      }
    
      // Return false if rejected
      return false; 
    }
    
    async function routes(fastify, options) {
    
      // 3. Register the plugins
      await fastify
        .register(auth)
        .register(bearerAuthPlugin, { 
          addHook: false, // Don't auto-hook the route, let fastify.auth handle it
          auth: verifyKeyAndSetUser, // Use the custom verification function
          verifyErrorLogLevel: 'debug' 
        })
        // 4. Custom decorator for anonymous access
        .decorate('allowAnonymous', function (req, reply, done) {
          if (req.headers.authorization) {
            // If an Authorization header is present, fail this strategy by returning an Error.
            // This forces fastify.auth to move on to the next strategy (verifyBearerAuth).
            return done(new Error('Auth header present, check bearer auth.')) 
          }
          
          // If no Authorization header, succeed and mark request as anonymous.
          req.isAnonymous = true;
          return done()
        })
    
      // 5. Define the route with the multi-auth preHandler
      fastify.route({
        method: 'GET',
        url: '/multiauth',
        preHandler: fastify.auth([
          fastify.allowAnonymous,
          fastify.verifyBearerAuth
        ]),
        handler: function (req, reply) {
          // 6. Check the explicit flags in the handler
          
          // Check for Bearer Auth success (highest priority)
          if (req.authData) { 
            reply.send({ 
              auth_strategy: 'bearer',
              user_data: req.authData
            });
          } else if (req.isAnonymous) {
            // Check for Anonymous success
            reply.send({ auth_strategy: 'anonymous' });
          } else {
            // Fallback (should ideally be unreachable if fastify.auth works)
            reply.code(401).send({ error: 'Auth failed unexpectedly' });
          }
        }
      });
    }
    
    fastify.register(routes);
    
    // 7. Start the server
    const start = async () => {
      try {
        await fastify.listen({ port: 3000 });
        console.log(`Server listening on http://localhost:3000`);
      } catch (err) {
        fastify.log.error(err);
        process.exit(1);
      }
    };
    start();
    $ curl -i http://localhost:3000/multiauth
    HTTP/1.1 200 OK
    content-type: application/json; charset=utf-8
    content-length: 29
    Date: Wed, 03 Dec 2025 17:59:44 GMT
    Connection: keep-alive
    Keep-Alive: timeout=72
    
    {"auth_strategy":"anonymous"}
    $ curl -i -H "Authorization: Bearer my-secret-token" http://localhost:3000/multiauth
    HTTP/1.1 200 OK
    content-type: application/json; charset=utf-8
    content-length: 109
    Date: Wed, 03 Dec 2025 18:00:23 GMT
    Connection: keep-alive
    Keep-Alive: timeout=72
    
    {"auth_strategy":"bearer","user_data":{"id":"my-secret-token","role":"authenticated_user","token_used":true}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    help wantedExtra attention is needed

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions