React Router 路由守卫

React Router 路由守卫

组件内路由守卫

1、下面是使用高阶组件实现路由守卫的示例代码:

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

const PrivateRoute = ({ component: Component, isAuthenticated, ...rest }) => (
  <Route
    {...rest}
    render={(props) =>
      isAuthenticated ? (
        <Component {...props} />
      ) : (
        <Redirect to={{ pathname: '/login', state: { from: props.location } }} />
      )
    }
  />
);

export default PrivateRoute;

在上面的代码中,PrivateRoute 是一个高阶组件,它接收一个组件作为参数,并返回一个新的组件。在 render 方法中,如果用户已经登录,则渲染传入的组件;否则,重定向到登录页面。通过使用该高阶组件,我们可以在需要进行权限验证的路由上使用 PrivateRoute 来保护路由,例如:

<Switch>
  <PrivateRoute exact path="/" component={Home} isAuthenticated={isAuthenticated} />
  <PrivateRoute path="/dashboard" component={Dashboard} isAuthenticated={isAuthenticated} />
  <Route path="/login" component={Login} />
</Switch>

其中 isAuthenticated 是一个布尔值,表示当前用户是否已经登录。

2、使用 函数组件或 render 属性来实现路由守卫

React Router 可以使用 Route 组件的 render 属性或函数式组件来实现路由守卫。

使用 render 属性时,可以传入一个函数,根据需要来渲染不同的组件或页面。在这个函数中可以实现路由守卫的逻辑,例如检查用户是否登录,根据用户角色判断是否有权限访问该页面等。如果不满足条件,可以返回一个重定向或提示信息,否则可以渲染目标组件或页面。

示例代码:

import { Route, Redirect } from 'react-router-dom';

function PrivateRoute({ component: Component, isAuth, ...rest }) {
  return (
    <Route
      {...rest}
      render={(props) =>
        isAuth ? (
          <Component {...props} />
        ) : (
          <Redirect
            to={{
              pathname: '/login',
              state: { from: props.location },
            }}
          />
        )
      }
    />
  );
}

在上面的示例中,PrivateRoute 组件接受三个参数:component,代表需要渲染的目标组件;isAuth,代表用户是否已登录;rest,代表其他参数,例如路由路径等。在 render 函数中,如果用户已登录,就渲染目标组件,否则返回一个重定向到登录页面。

使用函数式组件时,可以将需要实现路由守卫的逻辑直接写在函数组件中,例如在 useEffect 钩子函数中进行判断。如果不满足条件,可以使用 history.push 方法进行重定向。

import { useEffect } from 'react';
import { useHistory } from 'react-router-dom';

function PrivatePage() {
  const history = useHistory();
  const isAuth = true;

  useEffect(() => {
    if (!isAuth) {
      history.push('/login');
    }
  }, [isAuth, history]);

  return <div>Private Page</div>;
}

在上面的示例中,如果用户未登录,就会使用 history.push 方法将页面重定向到登录页面。这里的 useEffect 钩子函数会在组件渲染完成后执行,也可以根据需要添加其他依赖项。

全局路由守卫

虽然React没有路由守卫,但是我们可以通过高阶组件实现相关功能,使用方法如下

  1. 创建 AuthRoute.tsx 文件(位置可根据自己的习惯存放)
import React from 'react';
import { Navigate, useLocation } from 'react-router-dom';
const allowList = ['/login', '/register'];
const loginRoute = '/login';
const indexRoute = '/'
export default function AuthRoute(props) {
  const location = useLocation();
  // children 为子组件
  const { children } = props;
  // 根据 token 对路由进行权限校验,需要和后端配合使用
  // 这里的 token 一般是登陆成功之后拿到后端返回的 token 并通过 Cookie.set('token', token字符串, {
  //    expires: time_limit // 设置存放时间
  // })设置
  let token = false;
  if (token && token !== 'undefined') {
    // 有 token 的状态下禁止用户回到登录页,重定向到首页
    if (location.pathname === loginRoute) {
      return <Navigate to={indexRoute}></Navigate>;
    } else {
      // 其他路由均可正常跳转
      return <>{children}</>;
    }
  } else {
    // 无 token 的状态下,如果要跳转的路由是白名单中的路由,正常跳转
    if (allowList.includes(location.pathname || '')) {
      return <>{children}</>;
    } else {
      // 无 token 且非白名单路由,重定向至登录页
      return <Navigate to={loginRoute}></Navigate>;
    }
  }
}

//https://zhuanlan.zhihu.com/p/628935247 React Router 组件路由守卫(Route Guard)的机制
  1. 在 App.tsx中引入并设置
import React from 'react';
import ReactDOM from 'react-dom/client';
import './styles/basic.scss';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from 'react-router-dom';
import ThemeContext from './store/themeContext';
import store from './store';
import AuthRoute from './auth/auth';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <BrowserRouter>
      <ThemeContext.Provider
        value={{
          store
        }}
      >
        <AuthRoute>
          <App />
        </AuthRoute>
      </ThemeContext.Provider>
    </BrowserRouter>
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
### 使用 `spring-ollama-spring-boot-starter` 1.0.0-M6 和 Qwen 2.5 实现流式输出 为了实现流式输出,可以利用 `spring-ai-ollama-spring-boot-starter` 的特性以及 Qwen 模型的能力来构建响应式的应用程序。下面是一个详细的例子说明如何设置并使用这些组件。 #### 添加依赖项 首先,在项目的 `pom.xml` 文件中添加必要的 Maven 依赖: ```xml <dependency> <groupId>com.spring.ai</groupId> <artifactId>spring-ai-ollama-spring-boot-starter</artifactId> <version>1.0.0-M6</version> </dependency> <!-- 如果需要其他特定于Qwen的支持 --> <dependency> <groupId>com.qwen</groupId> <artifactId>qwen-client</artifactId> <version>2.5</version> </dependency> ``` #### 配置应用属性 接着配置 `application.properties` 或者 `application.yml` 来指定连接到 Ollama API 所需的信息和其他参数: ```yaml spring: ai: ollama: baseUrl: https://api.example.com/ollama # 替换成实际API地址 apiKey: YOUR_API_KEY_HERE # 设置Ollama服务的密钥 ``` #### 创建控制器类处理请求 创建一个新的 Spring 控制器用于接收客户端发起的消息,并通过调用 Qwen 进行自然语言处理返回实时更新的结果给前端页面或其他消费者。 ```java @RestController @RequestMapping("/stream") public class StreamController { @Autowired private OllamaService ollamaService; @GetMapping(value = "/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux<String> chat(@RequestParam String message) { return ollamaService.generateResponseStream(message); } } ``` 在这个例子中,当接收到 GET 请求 `/stream/chat?message=...` 后会触发聊天功能并将消息传递给 `generateResponseStream()` 方法来进行进一步处理[^1]。 #### 定义服务层逻辑 定义一个名为 `OllamaService` 的 Bean 对象负责与外部 RESTful Web Service (即 Ollama API)交互获取数据并向下游发送事件驱动的通知。 ```java @Service @Slf4j class OllamaServiceImpl implements OllamaService { private final WebClient webClient; @Value("${spring.ai.ollama.baseUrl}") private String baseUrl; @Value("${spring.ai.ollama.apiKey}") private String apiKey; public OllamaServiceImpl(WebClient.Builder builder){ this.webClient = builder.build(); } @Override public Flux<String> generateResponseStream(String inputText) { return webClient.post() .uri(baseUrl + "/v1/completions") .header(HttpHeaders.AUTHORIZATION, "Bearer " + apiKey) .body(BodyInserters.fromFormData("prompt", inputText)) .retrieve() .bodyToFlux(Map.class) .flatMap(response -> Flux.just((String) response.getOrDefault("choices", new ArrayList<>()).get(0))) .map(choice -> ((Map<?, ?>) choice).get("text").toString()) .doOnError(error -> log.error("Error while generating stream:", error)); } } ``` 这段代码展示了如何使用 Project Reactor 中的 `WebClient` 发送 HTTP POST 请求至目标 URL 并解析 JSON 响应中的文本部分作为字符串序列的一部分。注意这里假设了 API 返回的数据结构;具体字段名称可能因实际情况而异,请参照官方文档调整相应位置。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值