带有 IdentityServer4 和 oidc-client-js 的 ReactJS 错误:“没有响应代码”
Posted
技术标签:
【中文标题】带有 IdentityServer4 和 oidc-client-js 的 ReactJS 错误:“没有响应代码”【英文标题】:ReactJS with IdentityServer4 and oidc-client-js Error: "No code in response" 【发布时间】:2020-01-04 01:41:21 【问题描述】:我正在尝试通过 oidc-client-js
库让 ReactJS 与 IdentityServer4 一起工作。
问题
我单击登录按钮,然后重定向到 IdentityServer4,登录后,我重定向到 /login-callback
,然后从那里重定向到 /
,但我在控制台中收到以下错误:
我不确定自己做错了什么,但我尝试了各种方法,但似乎没有任何效果。
代码
所有代码都是开源的,sits here。
App.jsx
// other code ommited, but this is a route
<AuthHandshake path="/login-callback" />
AuthHandshake.jsx
import React from "react";
import AuthConsumer from "../AuthProvider/AuthProvider";
function AuthHandshake()
return <AuthConsumer>value => value.loginCallback()</AuthConsumer>;
export default AuthHandshake;
AuthProvider.jsx
import React, useState from "react";
import navigate from "@reach/router";
import UserManager, WebStorageStateStore from "oidc-client";
import AuthContext from "../../contexts/AuthContext";
import IDENTITY_CONFIG from "../../utils/authConfig";
IDENTITY_CONFIG.userStore = new WebStorageStateStore(
store: window.localStorage
);
const userManager = new UserManager(IDENTITY_CONFIG);
const login = () =>
console.log("Login button click handled.");
userManager.signinRedirect();
;
const logout = () =>
userManager.signoutRedirect();
;
export function AuthProvider(props)
const [user, setUser] = useState(null);
const loginCallback = () =>
userManager.signinRedirectCallback().then(
user =>
window.history.replaceState(
,
window.document.title,
window.location.origin
);
setUser(user);
navigate("/");
,
error =>
console.error(error);
);
;
const providerValue =
login: login,
logout: logout,
loginCallback: loginCallback,
isAuthenticated: user
;
const Provider = () =>
if (user)
return (
<AuthContext.Provider value=providerValue>
props.children
</AuthContext.Provider>
);
else
return <div className="auth-provider">props.children</div>;
;
return (
<>
<AuthContext.Provider value=providerValue>
props.children
</AuthContext.Provider>
</>
);
export const AuthConsumer = AuthContext.Consumer;
在 IdentityServer 方面,我已将注销后重定向设置为相同的东西 /login-callback
new Client
ClientId = "bejebeje-react-local",
ClientName = "Bejebeje ReactJS SPA Client",
AllowedGrantTypes = GrantTypes.Code,
RequirePkce = true,
RequireClientSecret = false,
RequireConsent = false,
RedirectUris = "http://localhost:1234/login-callback" ,
PostLogoutRedirectUris = "http://localhost:1234/logout-callback" ,
AllowedCorsOrigins = "http://localhost:1234" ,
AllowedScopes = "openid", "profile", "bejebeje-api-local" ,
AllowOfflineAccess = true,
RefreshTokenUsage = TokenUsage.ReUse,
我哪里错了?
【问题讨论】:
你有重定向到 https 的地方吗? oidc-client.js 好像是把状态保存在localstorage中,http和https是不一样的。 如果我是,我该如何调查?我会尝试看看 Fiddler 是否是这种情况。 【参考方案1】:在这里试试这个.. https://github.com/JwanKhalaf/Bejebeje.React/blob/bug/fix-no-code-response-on-redirect/src/components/AuthProvider/AuthProvider.jsx#L15
基本上,当您从客户端 (OIDC-client.js) 发送登录请求时,客户端会在 URL 中与登录请求一起发送一个唯一标识符 (State)。客户端将此值保存在您选择的存储选项(本地/会话)中。成功登录后,服务器在响应重定向 url 中发出令牌,其中还包括最初在登录请求中发送的唯一标识符客户端。在 chrome 开发者工具中观察登录请求 url 和响应 url。
当 OIDC 客户端库receives the sign-in response 时,它会从 URL 中获取唯一标识符,并与它在登录请求时保存在本地/会话存储中的值匹配。如果它们不匹配,客户端将不会接受服务器发出的令牌。
这只是一个额外的安全级别,以确保客户端不接受任何随机服务器或任何书签 URL 发出的任何令牌。
希望这会有所帮助。!!
usermanager.signinRedirect( state: bar: 15 );
【讨论】:
我听起来真的很愚蠢,但是当您将链接放在“试试这个”旁边时,只是链接到我的代码中的第 15 行?那是故意的吗?我只是有机会回到这个问题上,遇到了一些与工作相关的问题,对于延迟尝试这个问题表示歉意。【参考方案2】:我必须将response_mode: 'query'
添加到UserManager
。
var mgr = new Oidc.UserManager( response_mode: 'query' );
mgr.signinRedirectCallback().then(res =>
window.location = "/signin-callback";
).catch(error =>
window.location = "/";
)
【讨论】:
以上是关于带有 IdentityServer4 和 oidc-client-js 的 ReactJS 错误:“没有响应代码”的主要内容,如果未能解决你的问题,请参考以下文章
无法识别角色授权 - 带有 IdentityServer4 Cookie/Oidc 身份验证的 ASPNET CORE 5
自己发行 JWT 令牌与使用 IdentityServer4(OIDC) 进行 Web API
负载测试IdentityServer4给出异常:在唱歌后尝试请求signin-oidc路由时相关失败
在 Angular 中使用 IdentityServer4 + oidc-client-js 在空闲时注销用户