当我尝试在不使用任何异步函数的情况下执行身份验证时(例如,将用户名和密码与react中的硬编码值进行比较),一切工作都很顺利。
但是当我使用express和mongo执行身份验证时,登录时的重定向停止工作。如果我再次登录,那么重定向就会发生。受保护的路由仍然有效(如果用户没有登录,则重定向到登录页)。
下面是我在express+mongo IE中使用do auth的问题的一个小演示。异步还原。这并不像预期的那样有效。https://youtu.be/zxm5goyymzq
const ProtectedRoute = ({ component: Component, ...rest }) => {
const authState = useSelector(selectorAuth)
// const location = useLocation()
return (
<Route
{...rest}
render={props => {
if (authState.isUserLoggedIn) {
return <Component {...props} />
} else {
return (
<Redirect
to={{
pathname: "/",
state: {
from: props.location,
},
}}
/>
)
}
}}
/>
)
}
const App = () => {
return (
<Router>
<div tw="flex flex-col bg-green-100 min-h-screen">
<Navbar />
<Switch>
<Route exact path="/" component={Landing} />
<ProtectedRoute path="/home" component={Home} />
<ProtectedRoute path="/explore" component={Explore} />
<Route path="*" component={() => "404 Not found."} />
</Switch>
</div>
</Router>
)
}
const ModalLogin = props => {
const { loginModalBool, setLoginModalBool } = props
const [username, setUsername] = useState("")
const [password, setPassword] = useState("")
const dispatch = useDispatch()
const history = useHistory()
const attemptLogin = e => {
e.preventDefault()
dispatch(tryLogin(username, password))
history.push("/home")
}
return (
<div tw="flex flex-col text-center h-full w-64 bg-gray-200 text-gray-900 rounded-lg shadow-lg p-2 md:p-4 lg:p-6">
<div tw="flex flex-row justify-between">
<p tw="text-lg">Login</p>
<button tw="text-sm" onClick={() => setLoginModalBool(!loginModalBool)}>
close
</button>
</div>
<div tw="flex flex-col justify-around my-1">
<form onSubmit={attemptLogin} tw="">
<input
tw="my-1"
value={username}
onChange={e => setUsername(e.target.value)}
placeholder="username"
/>
<input
tw="my-1"
value={password}
onChange={e => setPassword(e.target.value)}
type="password"
placeholder="password"
/>
<button
type="submit"
tw="my-1 p-1 rounded bg-gray-800 text-gray-100 hover:bg-gray-900"
>
log in
</button>
</form>
</div>
</div>
)
}
import { createSlice } from "@reduxjs/toolkit"
import axios from "axios"
const initialState = {
isUserLoggedIn: false,
username: "",
}
export const authSlice = createSlice({
name: "auth",
initialState: initialState,
reducers: {
login: (state, action) => {
const user = action.payload
if (!user) return alert("Login failed. Incorrect username or password.")
state.username = user.username
state.isUserLoggedIn = true
},
logout: (state, action) => {
// window.localStorage.removeItem("loggedInUser")
state.username = ""
state.isUserLoggedIn = false
},
signup: (state, action) => {
const user = action.payload
state.username = user.data.username
state.isUserLoggedIn = true
},
},
})
export const tryLogin = (username, password) => {
return async dispatch => {
try {
const response = await axios.post("/api/auth/login", {
username: username,
password: password,
})
const user = {
token: response.headers["auth-token"],
username: response.data.username,
}
// window.localStorage.setItem("token", response.headers["auth-token"])
dispatch(login(user))
} catch (e) {
alert("Incorrect Username/Password.")
}
}
}
export const selectorAuth = state => state.auth
export const { login, logout } = authSlice.actions
export default authSlice.reducer
我是否错误地使用redux-toolkit的react-router?
这是Github回购
您的代码在登录后不定义重定向逻辑。你可以用两种方法来做。
第一:如果您希望您的路由在身份验证的情况下重定向,您可以为身份验证定义另一个重定向包装器。
const AuthRoute = ({ component: Component, ...rest }) => {
const authState = useSelector(selectorAuth)
const location = useLocation()
return (
<Route
{...rest}
render={props => {
if (!authState.isUserLoggedIn) {
return <Component {...props} />
} else {
return (
<Redirect
to={{
pathname: "/home",
state: {
from: location,
},
}}
/>
)
}
}}
/>
)
}
const App = () => {
return (
<Router>
<div tw="flex flex-col bg-green-100 min-h-screen">
<Navbar />
<Switch>
// It is for login users to redirect to home page
<AuthRoute exact path="/" component={Landing} />
<ProtectedRoute path="/home" component={Home} />
<ProtectedRoute path="/explore" component={Explore} />
<Route path="*" component={() => "404 Not found."} />
</Switch>
</div>
</Router>
)
}
第二:另一种方法可以是强制处理history.push()或history.replace():
const Layout = () => {
const authState = useSelector(selectorAuth);
const history = useHistory();
useEffect(() => {
// if isUserLoggedIn turned to true redirect to /home
if (authState.isUserLoggedIn) {
history.push("/home");
}
}, [authState.isUserLoggedIn]); // triggers when isUserLoggedIn changes
return (
<Switch>
<Route exact path="/" component={Landing} />
<ProtectedRoute path="/home" component={Home} />
<ProtectedRoute path="/explore" component={Explore} />
<Route path="*" component={() => "404 Not found."} />
</Switch>
);
};
const App = () => {
return (
<Router>
<div tw="flex flex-col bg-green-100 min-h-screen">
<Navbar />
<Layout />
</div>
</Router>
);
};
<Route exact path="/" component={Landing} />
<ProtectedRoute path="/home" component={Home} />
<ProtectedRoute path="/explore" component={Explore} />
<Route path="*" component={() => "404 Not found."} />
Reducer.js 我想在成功登录后重定向/主页。我如何重定向?
问题内容: 我想在我的 react / react-router / flux 应用程序中建立一个Facebook登录名。我在登录事件上注册了一个侦听器,并且希望将用户重定向到(如果他们已登录)。该怎么办?效果不佳,除非完全重新加载了页面。 问题答案: React Router v0.13 该实例从返回可以通过左右(或者,如果内部的阵营组件,你可以从它的上下文对象),以及包含的方法一样,你可以用它
应用程序要求如下所示: 1) 拥有一个带有简单用户名和密码的登录表单 2)一旦用户提交了登录表单,用户应该导航到主组件 问题: 在发送正确的用户名和密码后,服务器会进行身份验证并发送正确的令牌,但现在我设法在URL中显示正确的路由,但组件没有加载, 这是我的档案 登录信息 行动 index.js store.js 依赖列表 有人能帮我解释一下为什么这条路线不行吗,
记录器文件中的日志- org.springframework.Security.Access.event.loggerlistener-安全授权失败,原因是:org.springframework.Security.Access.accessdeniedexception:访问被拒绝;通过身份验证的主体:org.springframework.security.authentication.ano
问题内容: 我正在使用React Router v4并尝试实现一项功能,无论用户单击什么路由,他都会进入登录页面,即如果他尚未登录。 但登录后,他被重定向到他尝试在登录前访问的同一页面 我已经使用以下代码设法对其中的两条路线进行了此操作,但不确定这是否是最佳方法 现在,尽管这可以正常工作,但我不想为所有不同的路线重复一次相同的代码。所以有更好的方法吗? 现在,注销后,它什么也没显示,我希望它显示登
在开发模式下运行时,Spring Security重新定向到React前端(使用React路由器运行)的登录页面时,我遇到了一个配置问题。我相信我的前端没有接收到重定向,这是因为我对服务器端路由如何与SPA路由交互的noob理解。 我的开发前端web服务器(使用Facebook Create React App)在localhost:3000上运行,我的后端Spring Boot Tomcat在l