You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在基于类组件的Create React App中集成Passport.js?

Got it, let's walk through how to integrate Passport.js with your Create React App that uses class components. Since Passport is a backend authentication library, we’ll split this into two main parts: setting up the backend (with Express, since that’s common with Passport) and hooking up your React class components to it.


Backend Setup (Express + Passport)

First, you’ll need to configure Passport on your backend—this is where the authentication logic lives. Using the ADFS example you referenced, here’s a simplified setup:

  1. Install dependencies:

    npm install express passport passport-saml cors express-session
    
  2. Configure Passport and your server:

    const express = require('express');
    const passport = require('passport');
    const SamlStrategy = require('passport-saml').Strategy;
    const cors = require('cors');
    const session = require('express-session');
    
    // Initialize app
    const app = express();
    
    // CORS setup (allow your React app to communicate with the backend)
    app.use(cors({
      origin: 'http://localhost:3000', // Your React app URL
      credentials: true // Critical for passing session cookies
    }));
    
    // Session setup (required to persist login state)
    app.use(session({
      secret: 'your-strong-secret-key',
      resave: false,
      saveUninitialized: false
    }));
    
    // Initialize Passport
    app.use(passport.initialize());
    app.use(passport.session());
    
    // Configure ADFS SAML Strategy
    passport.use(new SamlStrategy({
      entryPoint: 'https://your-adfs-server/adfs/ls/',
      issuer: 'your-app-issuer-id',
      callbackURL: 'http://localhost:3001/auth/adfs/callback',
      // Add other required config (like certs) from your ADFS setup
    }, (profile, done) => {
      // Handle user lookup/creation here (e.g., check your database)
      // For simplicity, we'll just pass the profile through
      return done(null, profile);
    }));
    
    // Serialize/deserialize user for session storage
    passport.serializeUser((user, done) => done(null, user));
    passport.deserializeUser((user, done) => done(null, user));
    
    // Auth routes
    // Trigger ADFS login
    app.get('/auth/adfs', passport.authenticate('saml'));
    
    // ADFS callback route
    app.get('/auth/adfs/callback',
      passport.authenticate('saml', { failureRedirect: '/login' }),
      (req, res) => {
        // Redirect back to your React app after successful login
        res.redirect('http://localhost:3000/dashboard');
      }
    );
    
    // Endpoint to get current user info
    app.get('/api/user', (req, res) => {
      if (req.user) {
        res.json(req.user);
      } else {
        res.status(401).json({ message: 'Not authenticated' });
      }
    });
    
    app.listen(3001, () => console.log('Backend running on port 3001'));
    

React Class Component Integration

Now let’s connect your React class components to this backend. We’ll cover login triggers, checking auth state, and protecting routes.

1. Login Page Component

Create a login component that redirects users to the Passport auth endpoint:

import React from 'react';

class LoginPage extends React.Component {
  handleADFSLogin = () => {
    // Redirect to your backend's Passport login route
    window.location.href = 'http://localhost:3001/auth/adfs';
  };

  render() {
    return (
      <div className="login-container">
        <h1>Welcome to Our App</h1>
        <button onClick={this.handleADFSLogin} className="login-btn">
          Login with ADFS
        </button>
      </div>
    );
  }
}

export default LoginPage;

2. Protected Dashboard Component

Create a dashboard component that checks if the user is authenticated on mount:

import React from 'react';

class Dashboard extends React.Component {
  state = {
    user: null,
    loading: true,
    error: null
  };

  componentDidMount() {
    this.fetchCurrentUser();
  }

  fetchCurrentUser = async () => {
    try {
      const response = await fetch('http://localhost:3001/api/user', {
        credentials: 'include' // Critical: sends session cookies to backend
      });

      if (response.ok) {
        const user = await response.json();
        this.setState({ user, loading: false });
      } else {
        // User isn't authenticated—redirect to login
        this.props.history.push('/login');
      }
    } catch (err) {
      this.setState({ error: err.message, loading: false });
    }
  };

  render() {
    const { user, loading, error } = this.state;

    if (loading) return <div>Loading user info...</div>;
    if (error) return <div>Error: {error}</div>;

    return (
      <div className="dashboard">
        <h1>Welcome, {user.displayName}!</h1>
        <p>Your email: {user.email}</p>
        {/* Add other user-specific content here */}
      </div>
    );
  }
}

export default Dashboard;

3. Protected Route Higher-Order Component (HOC)

To reuse auth checks across multiple components, create an HOC that wraps protected routes:

import React from 'react';
import { Redirect } from 'react-router-dom';

const requireAuth = (WrappedComponent) => {
  return class extends React.Component {
    state = {
      isAuthenticated: false,
      loading: true
    };

    componentDidMount() {
      this.checkAuthStatus();
    }

    checkAuthStatus = async () => {
      try {
        const response = await fetch('http://localhost:3001/api/user', {
          credentials: 'include'
        });
        this.setState({ isAuthenticated: response.ok, loading: false });
      } catch (err) {
        this.setState({ isAuthenticated: false, loading: false });
      }
    };

    render() {
      const { isAuthenticated, loading } = this.state;

      if (loading) return <div>Checking auth...</div>;
      return isAuthenticated ? (
        <WrappedComponent {...this.props} />
      ) : (
        <Redirect to="/login" />
      );
    }
  };
};

export default requireAuth;

Then use it to wrap your protected components in your router setup:

import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import LoginPage from './LoginPage';
import Dashboard from './Dashboard';
import requireAuth from './requireAuth';

function App() {
  return (
    <Router>
      <Switch>
        <Route path="/login" component={LoginPage} />
        <Route path="/dashboard" component={requireAuth(Dashboard)} />
        <Route path="/" exact component={LoginPage} />
      </Switch>
    </Router>
  );
}

export default App;

Key Notes & Troubleshooting

  • CORS & Credentials: Make sure your backend’s CORS config includes credentials: true and your React fetch requests include credentials: 'include'—this is how session cookies are passed between frontend and backend.
  • Session Persistence: If users are logged out on page refresh, double-check your backend session config (ensure the secret is set and session middleware is correctly ordered).
  • ADFS Config: Verify your ADFS strategy settings (entryPoint, issuer, callbackURL) match what’s configured on your ADFS server—mismatches here will cause authentication failures.

内容的提问来源于stack exchange,提问作者user25010

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:23:08