简体   繁体   中英

How to popup login screen(Azure AD) without using a button when accessing URL(local host in my case) directly?

I have created a basic application of react in which I have implemented the concept of routing and for authentication I have used Azure AD. Its working fine when I try to login using the login button but I want that when I try to access the home page it automatically redirects to the login page(Microsoft login) without clicking any button.

This is my code for "App.js" and in "AuthConfig" I have simply declared my clientId, redirecturi, scopes and authority.


import Prices from "./pages/Prices";
import Ticket from "./pages/Ticket";
import Money from "./pages/Money";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import {config} from "./AuthConfig";
import {PublicClientApplication} from '@azure/msal-browser';
import React from "react";

class App extends React.Component<any, any>{
  publicClientApplication: PublicClientApplication;  
  constructor(props){
    super(props);
    this.state = {
      error: null,
      isAuthenticated: false,
      user:{}
    };
    this.login=this.login.bind(this)
    
    this.publicClientApplication = new PublicClientApplication({
      auth:{
        clientId: config.appId,
        redirectUri: config.redirectUri,
        authority: config.authority
      },
      cache:{
        cacheLocation: "sessionStorage",
        storeAuthStateInCookie: false
      }
    });
  }
  async login(){
    try{
      
      await this.publicClientApplication.loginPopup(
        {
        scopes: config.scopes,
        prompt:"select_account"
      });
      this.setState({isAuthenticated:true})
  }
  catch(err){
    this.setState({
      isAuthenticated:false,
      user:{},
      error:err
    });
  }
}
logout(){
  this.publicClientApplication.logoutPopup();
}

render() {
  return(
    <div className="App">
     
      {this.state.isAuthenticated ? <p>
        <BrowserRouter>
        <Routes>
          <Route path="/" element={<Prices />} />
        </Routes>
      </BrowserRouter>
      </p>: 
      <p>
        <button onClick={() => this.login()} > Login </button>
      </p>
      }
      <BrowserRouter>
        <Routes>         
          <Route path="/Money" element={<Money />}></Route>
          <Route path="/Ticket" element={<Ticket/>}></Route>
        </Routes>
      </BrowserRouter>
      
     
    </div>
  );
}
}
export default App;

If you simply want the login function to be called automatically when the App component mounts instead of when the button is clicked you can do this in the componentDidMount lifecycle method.

Example:

class App extends React.Component<any, any> {
  publicClientApplication: PublicClientApplication;

  constructor(props) {
    super(props);
    this.state = {
      error: null,
      isAuthenticated: false,
      user: {}
    };

    this.publicClientApplication = new PublicClientApplication({
      auth: {
        clientId: config.appId,
        redirectUri: config.redirectUri,
        authority: config.authority
      },
      cache: {
        cacheLocation: "sessionStorage",
        storeAuthStateInCookie: false
      }
    });
  }

  componentDidMount() {
    this.login();
  }

  login = sync () => {
    try {
      await this.publicClientApplication.loginPopup({
        scopes: config.scopes,
        prompt: "select_account"
      });
      this.setState({ isAuthenticated: true });
    } catch(err) {
      this.setState({
        isAuthenticated: false,
        user: {},
        error: err
      });
    }
  }

  logout() {
    this.publicClientApplication.logoutPopup();
  }

  render() {
    return(
      <div className="App">
        {this.state.isAuthenticated && (
          <BrowserRouter>
            <Routes>
              <Route path="/" element={<Prices />} />
            </Routes>
          </BrowserRouter>
        )}
        <BrowserRouter>
          <Routes>
            <Route path="/Money" element={<Money />} />
            <Route path="/Ticket" element={<Ticket />} />
          </Routes>
        </BrowserRouter>
      </div>
    );
  }
}

I'm also not sure what is going on with usage of two routers, you'll very likely want to merge these so all routes are rendered within the same single routing context.

Example:

<div className="App">
  <BrowserRouter>
    <Routes>
      <Route
        path="/"
        element={this.state.isAuthenticated ? <Prices /> : null}
      />
      <Route path="/Money" element={<Money />} />
      <Route path="/Ticket" element={<Ticket />} />
    </Routes>
  </BrowserRouter>
</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM