Implementing Passport authentication for Steam, transitioning from Express to NestJS

I have embarked on the task of transitioning an express project to nestjs. How can I achieve the same functionality in Nestjs as shown in the working code snippet from Express below? (The code simply redirects to the Steam sign-in page)

/* eslint-disable space-before-function-paren */
// Include all required packages
var express = require('express');
var passport = require('passport');
var session = require('express-session');
var passportSteam = require('passport-steam');
var SteamStrategy = passportSteam.Strategy;
var app = express();
// Define a port
var port = 4000;
// Start the server
app.listen(port, () => {
  console.log('Listening, port ' + port);
});

// Setup the SteamStrategy
passport.serializeUser((user, done) => {
  done(null, user);
});

passport.deserializeUser((user, done) => {
  done(null, user);
});

// Initialize Strategy
passport.use(
  new SteamStrategy(
    {
      returnURL: 'http://localhost:' + port + '/api/auth/steam/return',
      realm: 'http://localhost:' + port + '/',
      apiKey: 'My API key',
    },
    function (identifier, profile, done) {
      process.nextTick(function () {
        profile.identifier = identifier;
        return done(null, profile);
      });
    }
  )
);

app.use(
  session({
    secret: 'Whatever_You_Want',
    saveUninitialized: true,
    resave: false,
    cookie: {
      maxAge: 3600000,
    },
  })
);
app.use(passport.initialize());
app.use(passport.session());

// Routes
app.get('/', (req, res) => {
  res.send(req.user);
});
app.get(
  '/api/auth/steam',
  passport.authenticate('steam', { failureRedirect: '/' }),
  function (req, res) {
    res.redirect('/');
  }
);

app.get(
  '/api/auth/steam/return',
  passport.authenticate('steam', { failureRedirect: '/' }),
  function (req, res) {
    res.redirect('/');
  }
);

How can I replicate this functionality in Nestjs? If I wish to create custom middleware for the passport library (serializeUser, deserializeUser), how would I go about it? The official Nestjs documentation provides examples of custom middlewares like the one below:

export function logger(req: Request, res: Response, next: NextFunction) {
  console.log(`Request...`);
  next();
};

But how do I incorporate passport middleware?

Answer №1

For those still seeking guidance, the following approach is recommended per the Nestjs documentation:

Assuming familiarity with setting up a nest application and handling steam authentication

  1. Begin by creating a controller dedicated to the /steam/auth path:
import { Controller, Get, Req, Res, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { Request, Response } from 'express';
import { AuthService } from './auth.service';

@Controller('auth')
export class AuthController {
 constructor(private readonly authService: AuthService) {}

 @Get('steam')
 @UseGuards(AuthGuard('steam'))
 steamLogin() {}
}
  1. Next, configure the steam strategy in a separate file named steam.strategy:
import { Strategy } from 'passport-steam';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';


@Injectable()
export class SteamStrategy extends PassportStrategy(Strategy) { 
    super({
      returnURL: 'http://localhost:3001/auth/return',
      realm: 'http://localhost:3001/',
      apiKey: 'Your API key',
    });
  }
  validate(identifier, profile, done) {
     // insert custom logic post successful login here
     
  }
  1. Remember to import the strategy within your auth.module:
import { Module } from '@nestjs/common';
import { SteamStrategy } from './steam.strategy';
@Module({
  providers: [SteamStrategy],
})
export class AuthModule {}

That wraps it up. Following this setup, you can proceed as usual with express!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What to do when encountering the error "Uncaught (in promise) SyntaxError: Unexpected end of JSON input"?

While signing in to my website from localhost is successful, I encounter an issue when trying to do the same from my production build. The login attempt from the prod build (hosted on Vercel) does not post to , but instead goes to . I am perplexed by the a ...

The error message "Property 'listingSub$' is not initialized in the constructor and is not definitely assigned" needs to be addressed and fixed in the code

import { Subscription } from "rxjs"; @Component({ selector: 'app-listing-detail', templateUrl: './listing-detail.component.html', styleUrls: ['./listing-detail.component.scss'] }) export class ListingDetailCo ...

Unable to transmit Javascript array to PHP using Ajax

I've been pulling my hair out over a seemingly simple problem. Here is the JavaScript array that's causing me trouble: var orderDetailsArray = new Array(); orderDetailsArray[0] = 'test 1'; orderDetailsArray[1] = 'test ...

Specify the dependencies in the package.json file to ensure that the React package designed for React v17 is compatible with React v18 as well

Recently, I developed an npm package using React v17.0.2. The structure of the package.json file is as follows: { "name": "shoe-store", "version": "0.1.0", "private": true, "dependencies": ...

Deliver a response using Express.js before the execution process is completed

Within an Express application, my goal is to achieve the following: app.get('/some/route', someMiddleWare(), function(req, res){ var status = undefined; if( /*someCondition*/ ) status = 200; else status = 403 res.status(status). ...

Selenium EventFiringWebDriver JavaScript: There is a SyntaxError due to a missing closing parenthesis after an argument in

Attempting to run a javaScript command through the EventFiringWebDriver class in Selenium. EventFiringWebDriver eventFiringWebDriver = new EventFiringWebDriver(driver); eventFiringWebDriver.executeScript("document.querySelector('[ng-reflect-title=&ap ...

Sending a file stream with specific file name and extension in NodeJS: A comprehensive guide

Currently, I am utilizing nodejs to transmit file streams to express response var fileReadStream = fs.createReadStream(filePath); fileReadStream.pipe(res); However, the issue arises on the front-end where the file is solely downloadable with the "download ...

When is the right time to develop a Node.js application using Typescript with dockerization

Currently, I am developing a full stack TypeScript application using Express for the server and React for the client. The folder structure of my project is organized as shown below: . ├──client/ <-- React app ├──server/ <-- Express serve ...

The argument provided must be a string comprising of either 12 bytes, a string containing 24 hex characters, or an integer in order to avoid a BSONTypeError

After building a CRUD application using the MERN stack, I attempted to implement a search operation but encountered an error: BSONTypeError: Argument passed in must be a string of 12 bytes or a string of 24 hex characters or an integer Below is the code ...

Programmatically toggle the visibility of an ion fab button

Looking for assistance in finding a method to toggle the visibility of a particular button within the collection of buttons in an ion-fab ...

Using createStyles in TypeScript to align content with justifyContent

Within my toolbar, I have two icons positioned on the left end. At the moment, I am applying this specific styling approach: const useStyles = makeStyles((theme: Theme) => createStyles({ root: { display: 'flex', }, appBar: ...

Using style binding and ngStyle doesn't appear to be effective for setting a background image within a DIV element in Angular5

After facing difficulties in customizing the spacing of Angular material cards, I decided to create my own cards. However, during this process, I encountered an issue where I needed to set an image as a background inside a div. Despite trying various CSS ...

Developing a Mongoose organization/class framework?

Currently, I'm in the process of developing a web application using Node.js, Express, and Mongoose/MongoDB. An important query has arisen regarding how to effectively organize and structure methods related to Mongoose. It's necessary for me to u ...

When importing modules in node.js, the presence of a function can overwrite another function even if it

Within this code snippet, I am utilizing Express.js. //index.js app.use('/',routes()); //app/routes.js module.exports = function() { express = require('express'); const loggedUserProfileController = require('../controller ...

How can one get rid of a sudden strong beginning?

Recently, I delved into the world of CSS animation and encountered a frustrating issue. I've tried numerous methods and workarounds to achieve a smoothly looping animation without interruptions. Despite my efforts, I have not been able to replicate th ...

Tips for sending JSON data to .js files

I am experiencing an issue here. In locations.php, I have the following code to generate JSON data: <?php $locations = array( array('2479 Murphy Court', "Minneapolis, MN 55402", "$36,000", 48.87, 2.29, "property-detail.html", ...

Personalized payment fields: Revealing/concealing data using a selector

Following this successful solution: // Incorporating an external jQuery/JS file function cfields_scripts() { // IMPORTANT NOTE: // When using a child theme, replace get_template_directory_uri() with get_stylesheet_directory_uri() // Place th ...

Error message: When the mouse hovers over, display the chart(.js) results in TypeError: t is

I encountered a persistent error that I just can't seem to resolve. My goal is to showcase a chart using Chart.js when the mouse hovers over the canvas. However, upon hovering over the canvas, I keep getting a TypeError: t is null error. Error: { ...

What steps can I take to address the problem in iOS 17 where sound is coming from the earpiece instead of the speaker during camera activation?

I have a Progressive Web App where I use the getUserMedia() API to access the camera and HTML audio tags for handling media content. However, ever since updating to iOS 17, I've faced an issue where audio plays through the earpiece instead of the medi ...

Steps to initiate my selenium-standalone server: Execute the command "selenium-standalone start"

I'm currently facing a challenge while trying to execute a test script in WebDriverIO. After cloning the code from wdio-cucumber-framework, I am unable to get selenium-standalone to start properly. The error message indicates an issue with geckodriv ...