问题描述
我想在我的客户端应用程序中实现授权,但我在使用 Keycloak 的 React 应用程序中更新令牌时遇到问题。
App.js
import keycloak from "../../keycloak";
const App = () => {
const handleOnEvent = async (event,error) => {
if(event === 'onTokenExpired'){
keycloak.updateToken(300).then(
(response) => {
//I want to update my existing Token
alert("response: ",response )
})
.catch(error => {
console.log("error: ",error)
})
}
}
return (
<>
<ReactKeycloakProvider
authClient={keycloak}
onEvent={(event,error) => handleOnEvent(event,error)}>
<AppRouter/>
</ReactKeycloakProvider>
</>)
}
export default App;
标题
const Header = () => {
const {keycloak,initialized} = useKeycloak()
useEffect(() => {
if(keycloak.authenticated){
alert(JSON.stringify(keycloak))
localStorage.setItem("keycloakToken",keycloak.token); //set keycloak token to localStorag
localStorage.setItem("keycloakRefreshToken",keycloak.refreshToken); // set refresh token
setJWTToken(keycloak.token) //set to axios Authorization Bearer
}
},[keycloak.authenticated])
return(
<>
{
keycloak && !keycloak.authenticated && <UnloggedHeader keycloak={keycloak}/>
}
{
keycloak && keycloak.authenticated && <LoggedHeader keycloak={keycloak}/>
}
</>
)
}
export default Header
UnloggedHeader
function UnloggedHeader({keycloak}){
const signIn = () => {
keycloak.login()
}
return (
<div style={{minWidth: '1100px'}}>
<AppBar position="sticky" color='transparent'>
<Toolbar>
<Button onClick={signIn} variant="contained" color="primary">Login</Button>
<Typography variant="body1" component="h6">Unlogged</Typography>
</Toolbar>
</AppBar>
</div>
);
}
export default UnloggedHeader
LoggedHeader
function LoggedHeader({keycloak}){
let history = useHistory()
const [anchorEl,setAnchorEl] = React.useState(null);
const isMenuOpen = Boolean(anchorEl);
const handleProfileMenuOpen = (event) => {
setAnchorEl(event.currentTarget);
};
const [userInfo,setUserInfo] = useState()
useEffect(() => {
keycloak.loadUserInfo().then(userInfo => {
setUserInfo(userInfo)
localStorage.setItem("username",userInfo.preferred_username); // set username of user
})
},[])
const handleMenuClose = () => {
setAnchorEl(null);
};
const handleUserLogoutClick = () => {
keycloak.logout()
history.push("/")
}
return (
<div style={{minWidth: '1100px'}}>
<AppBar position="sticky" color='transparent'>
<Toolbar>
<Typography variant="body1" component="h6">{userInfo !== undefined ? userInfo.preferred_username : "EMPTY"}</Typography>
<ExpandMoreIcon/>
<Button onClick={handleUserLogoutClick} variant="contained" color="primary">Log out</Button>
</Toolbar>
</AppBar>
{renderMenu}
</div>
);
}
export default LoggedHeader
keycloak.js
import Keycloak from 'keycloak-js'
const keycloakConfig = {
url: 'http://10.192.168.72:8080/auth/',realm: 'Realm12',clientId: 'client',}
const keycloak = new Keycloak(keycloakConfig);
export default keycloak
我需要向 ReactKeycloakProvider 提供什么才能在过期时获取新的 access_token? 如何基于refreshToken值获取accessToken?由于获得此值,我不知道是哪个方法或端点。我在网络上找不到这种问题。
请帮帮我!
解决方法
我在这一点上做了一些调查,因为我无法通过刷新令牌获得新令牌,这对我有用
我使用了 Keycloak 端点:
https://<yourAuthLink>/auth/realms/<relmName>/protocol/openid-connect/token
带有标题对象
headers: {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'}
身体就会变成那样:
body: "client_id"=<clientId>&"grant_type"="refresh_token"&"refresh_token"=<refreshToken>&"client_secret"=<clientSecret>
这将返回包含 access_token 的响应,您将其用作令牌和 refresh_token 以在到期时间之前再次使用它