【问题标题】:Making Asp.Net core route first and then making to React route next先制作 Asp.Net 核心路由,然后再制作到 React 路由
【发布时间】:2019-08-02 13:22:37
【问题描述】:

我是新来的反应,但不是 asp.net 核心应用程序开发。我正在尝试在 Visual Studio 中使用 asp.net core + react 模板创建一个反应应用程序。我正在尝试首先执行 Asp.Net MVC 路由来调用具有 [Authorize] 属性的控制器操作,以确保用户已通过身份验证。我没有任何东西可以在 Asp.Net MVC 视图中显示。一旦用户通过 asp.net mvc 控制器操作进行身份验证,我想立即重定向用户以响应默认路由。是否有任何特定的路由机制来实现这一点。

现在我的应用程序根据路由通过控制器和动作,并在控制器动作定义的视图处停止。我正在尝试了解如何重定向用户现在使用反应路线。我尝试使用 return redirecttoaction 和 returnredirecttoroute 但没有运气。

我的 Asp.Net Core MVC 操作

[Authorize]
public ActionResult Index()
{
    var IsAuthenticated = HttpContext.User.Identity.IsAuthenticated;
    var UserName = "Guest";
    if (IsAuthenticated)
    {
        UserName = HttpContext.User.Identity.Name;
    }
    TempData["userName"] = UserName;

    //return View();
    return Redirect("my react first page");
}

我试过 return Redirect("my react first page");

用于路由的我的启动文件方法

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
                else
                {
                    app.UseExceptionHandler("/Error");
                    app.UseHsts();
                }

                app.UseHttpsRedirection();
                app.UseStaticFiles();
                app.UseSpaStaticFiles();
                app.UseAuthentication();


//MVC Part. I am trying this to authorize as FIRST step
                app.UseMvc(routes =>
                {
                    routes.MapRoute(
                        name: "default",
                        template: "{controller=DataAccess}/{action=Index}/{id?}");
                });

// React part I am trying this to be called once Authentication is done in controller action. Trying to call this as a SECOND step

                app.UseSpa(spa =>
                {
                    spa.Options.SourcePath = "ClientApp";

                    if (env.IsDevelopment())
                    {
                        spa.UseReactDevelopmentServer(npmScript: "start");
                    }
                });
            }

如果我进行重定向并强制响应路由,缺少响应路由功能是否会出现任何问题?如果我进行重定向,我看到这个 spa.UseReactDevelopmentServer(npmScript: "start"); 会花费更多时间来显示超时。任何可以将用户重定向到控制器操作的解决方案都可以完成所有授权并使用反应默认路由机制?

是否有任何选项可以先运行反应服务器并进行路由,因为启动服务器需要更多时间导致超时。

注意:我使用 Create-React-App 来创建我的应用程序。

【问题讨论】:

  • MVC 身份验证是服务器端,React 路由是客户端。对于 SPA 和 MVC 后端,您的客户端路由由 react 控制,然后 react 向后端发送请求以请求资源并检查身份验证。如果你想控制对react页面的访问,可以参考Permission checks from components in a React/Redux application
  • 你想让两个(reactjs 和 .net core)不同的服务器同时运行吗?

标签: c# reactjs asp.net-core asp.net-core-mvc


【解决方案1】:

您可以将主反应页面设置为它返回的视图。

然后您的控制器可以返回该视图,或者您可以创建一个控制器来返回该视图并重定向到那里。

【讨论】:

    【解决方案2】:

    我已经用 .net 核心解决了这个问题,并且也做出了反应。

    反应: 为您的路由设置 HOC。让那个 hoc 打到后端,看看用户是否被授权。如果不重定向到登录。

    .Net 核心: 为 HOC 设置一个基本路径来命中并验证用户是否被授权。

    这是我的 github 上的完整文章(虽然它带有 jwt 令牌):https://github.com/moh704/AuthenticationExample

    //Routing with HOC:
    class App extends Component {
      render() {
        return (
            <Provider store={store}>
              <ConnectedRouter history={history}>
                <Switch>
                  <Route component={SignIn} exact path='/'/>
                  <PrivateRoute component={Home} path='/Home'/> //Token will have to be valid in order to access this route.
                </Switch>
              </ConnectedRouter>
            </Provider>
        );
      }
    }
    
    //PrivateRoute Component:
    interface PrivateRouteProps extends RouteProps {
      component:
        | React.ComponentType<RouteComponentProps<any>>
        | React.ComponentType<any>;
    }
    
    interface State {
      validatingUser: boolean,
      userAllowed: boolean
    }
    
    class PrivateRouter extends React.Component<PrivateRouteProps, State> {
      state: State = {
        validatingUser: true,
        userAllowed: false
      };
    
      componentDidMount(): void {
        this.checkUserStatus();
      }
    
      checkUserStatus = async() => {
        const token = localStorage.getItem('token');
        if (token){
          await axios.get(UserRoutes.GET_TOKEN_STATUS)
            .then(() => this.setState({userAllowed: true, validatingUser: false}))
            .catch(() => this.setState({userAllowed: true, validatingUser: false}));
        } else
          this.setState({userAllowed: false, validatingUser: false});
      };
    
      render() {
        const { component, ...rest} = this.props;
        return(
          !this.state.validatingUser ?
            <Route
              {...rest}
              render={props =>
                this.state.userAllowed ? (
                  <this.props.component {...props} />
                ) : (
                  <Redirect // <---- **Redirect magic happens here you're aiming for**
                    to={{
                      pathname: "/"
                    }}
                  />
                )
              }
            /> : <div>loading...</div>
        )
      }
    }
    export default PrivateRouter;
    

    对于 .net,只需创建一个简单的 get 路由,如果获得授权,它将返回正常。否则,它会返回一个未授权的或禁止的:

    [HttpGet]
    [Authorize]
    public IActionResult CheckUserState()
    {
       return Ok();
    }
    

    【讨论】:

      【解决方案3】:

      我不建议在服务器端进行任何类型的路由或重定向。这将使开发复杂化,并且工作量也会增加一倍。更简单的方法是在客户端处理路由或重定向。从代码的角度来看,这也将更易于维护。

      从 React 中,当用户登录时,调用您的控制器操作来进行身份验证/授权。然后,您可以根据响应使用 React 进行适当的重定向(例如,成功的登录重定向到用户的仪表板,失败的登录显示身份验证错误等)

      【讨论】:

        【解决方案4】:

        您应该在 react 中设置客户端路由,并在 asp.net 核心中设置服务器端路由。

        请注意,客户端路由仅限于浏览器。服务器不知道它们。

        当您尝试在响应中更改页面时,浏览器(不向服务器发送请求)将用户重定向到其他页面 - 前提是您不需要来自服务器的任何其他信息来进行此重定向。

        在我看来,您应该以这样一种方式设计应用程序,即您的服务器不应直接影响客户端路由中定义的路由。

        基于asp.net服务器上的某些决定进行路由的理想流程(在我看来)是:

        • 客户端调用服务器做出决定
        • 服务器发回响应以做出反应
        • React 然后解释响应并决定是否重定向。
        • 如果用户被重定向,那么它应该被重定向到哪里。

        此逻辑(或任何其他类似逻辑)还将使您的服务器端逻辑与客户端技术完全分离。

        【讨论】:

          【解决方案5】:

          不要为两者设置相同的路由,让服务器找到非 React 视图,让 React 拥有自己的路由和视图/模板

          【讨论】:

            猜你喜欢
            • 2017-03-02
            • 1970-01-01
            • 1970-01-01
            • 2020-04-09
            • 1970-01-01
            • 2021-09-07
            • 1970-01-01
            • 2018-07-06
            • 2020-06-08
            相关资源
            最近更新 更多